27 #include <Classes.hpp>
28 #include <Controls.hpp>
29 #include <StdCtrls.hpp>
31 #include <Buttons.hpp>
32 #include <ExtCtrls.hpp>
34 #include <Dialogs.hpp>
35 #include <Graphics.hpp>
36 #include <ComCtrls.hpp>
59 #include <Filectrl.hpp>
62 #include <Vcl.HTMLHelpViewer.hpp>
63 #pragma package(smart_init)
64 #pragma link "Vcl.HTMLHelpViewer" //added at v2.0.0 for access to the .chm help file
65 #pragma resource "*.dfm"
84 Screen->Cursor = TCursor(-11);
150 "program operation may be restricted");
153 Application->HelpFile = AnsiString(
CurDir +
"\\Help.chm");
161 int DispW = (Screen->Width - 64) / 16;
162 int DispH = (Screen->Height - 192) / 16;
166 Display =
new TDisplay(
MainScreen,
PerformanceLogBox,
OutputLog1,
OutputLog2,
OutputLog3,
OutputLog4,
OutputLog5,
OutputLog6,
OutputLog7,
OutputLog8,
235 std::ifstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
236 if(ConfigFile.fail())
239 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
245 "This program is free software released under the terms of the GNU General Public License Version 3, as published by the Free Software Foundation. "
246 "It may be used or redistributed in accordance with that license and is released in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
247 "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details - "
248 "you should have received a copy along with this program but if not see <http://www.gnu.org/licenses/>.");
252 AnsiString ConfigStr =
"";
260 AnsiString ConfigValue = ConfigStr.SubString(9, ConfigStr.Length() - 8);
261 if(ConfigStr.SubString(1, 8) ==
"Signals=")
263 if(ConfigValue ==
"right")
275 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
284 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
291 if(ConfigStr.SubString(1, 8) ==
"BgndCol=")
295 if(ConfigValue ==
"white")
299 else if(ConfigValue ==
"blue")
304 if(ConfigStr.SubString(1, 8) ==
"RLYLocn=")
306 if(DirectoryExists(ConfigValue))
312 else if(ConfigStr.SubString(1, 8) ==
"TTBLocn=")
314 if(DirectoryExists(ConfigValue))
316 TimetableDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
317 SaveTTDialog->InitialDir = ConfigStr.SubString(9, ConfigStr.Length() - 8);
320 else if(ConfigStr.SubString(1, 8) ==
"SSNLocn=")
322 if(DirectoryExists(ConfigValue))
328 while(!ConfigFile.eof());
426 SpeedButton96->Glyph->LoadFromResourceName(0,
"ConcourseGlyph");
490 FontButton->Glyph->LoadFromResourceName(0,
"FontGraphic");
491 HomeButton->Glyph->LoadFromResourceName(0,
"Home");
510 SetGapsButton->Glyph->LoadFromResourceName(0,
"ConnectGaps");
521 CallOnImage->Picture->Bitmap->LoadFromResourceName(0,
"CallingOn");
522 CrashImage->Picture->Bitmap->LoadFromResourceName(0,
"CrashWarning");
523 DerailImage->Picture->Bitmap->LoadFromResourceName(0,
"DerailWarning");
524 SignalStopImage->Picture->Bitmap->LoadFromResourceName(0,
"SignalStopWarning");
525 SPADImage->Picture->Bitmap->LoadFromResourceName(0,
"SPADWarning");
526 TrainFailedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrainFailedWarning");
528 DistanceKey->Picture->Bitmap->LoadFromResourceName(0,
"DistanceKey");
529 PrefDirKey->Picture->Bitmap->LoadFromResourceName(0,
"PrefDirKey");
531 TrackLinkedImage->Picture->Bitmap->LoadFromResourceName(0,
"TrackLinkedGraphic");
533 GapsNotSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsNotSetGraphic");
534 GapsSetImage->Picture->Bitmap->LoadFromResourceName(0,
"GapsSetGraphic");
545 AnsiString NL =
'\n';
546 const AnsiString TTLabelStr1 =
"Start new train" + NL +
"Start new service from a split" + NL +
"Start new service from another service" + NL +
547 "Start new non-repeating shuttle finish service" + NL +
"Start new shuttle train at a timetabled stop" + NL +
548 "Start new shuttle service from a feeder";
550 const AnsiString TTLabelStr2 =
"Pass" + NL +
"Be joined by another train" + NL +
"Front split" + NL +
"Rear split" + NL +
"Change direction of train";
552 const AnsiString TTLabelStr3 =
"Finish && form a new service" + NL +
"Finish && join another train" + NL +
"Finish && exit railway" + NL +
553 "Finish && repeat shuttle, finally remain here" + NL +
"Finish && repeat shuttle, finally form a finishing service" + NL +
554 "Finish non-repeating shuttle feeder service" + NL +
"Finish && remain here";
556 const AnsiString TTLabelStr4 =
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
557 "HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
"HH:MM" + NL +
" " + NL +
"R";
559 const AnsiString TTLabelStr5 =
"HH:MM ';' Location" + NL +
"HH:MM ';' HH:MM ';' Location";
561 const AnsiString TTLabelStr6 =
"+ rear element ID - space - front element ID [+ optional ';S']" + NL +
"+ ref. of the train that splits" + NL +
562 "+ other service ref." + NL +
"+ shuttle service ref." + NL +
"+ rear element ID - space - front element ID ';' linked shuttle ref." + NL +
563 "+ linked shuttle service ref. ';' feeder service ref." + NL +
"+ location" + NL +
"+ joining train ref." + NL +
"+ new service ref." + NL +
564 "+ new service ref." + NL +
" " + NL +
"+ new service ref." + NL +
"+ ref. of train to join" + NL +
565 "+ list of valid exit element IDs (at least 1) separated by spaces" + NL +
"+ linked shuttle service ref.";
567 const AnsiString TTLabelStr7 =
"Arrival OR departure time (program will determine which from the context) + location." + NL +
568 "Arrival time, departure time (with no events between) + location";
570 const AnsiString TTLabelStr9 =
"Timetable entries" + NL +
"(service references etc.)";
571 const AnsiString TTLabelStr11 =
"Timetable" + NL +
"start time";
573 const AnsiString TTLabelStr12 =
"NB: WITHIN SERVICES commas must" + NL +
"not be used (have special meanings)," + NL +
574 "and semicolons may only be used to" + NL +
"separate service components.";
576 const AnsiString TTLabelStr13 =
"+ linked shuttle service ref. ';' finishing service ref." + NL +
"+ linked shuttle service ref.";
578 const AnsiString TTLabelStr15 =
"Repeat the service + ';' minutes between repeats ';' digit increment ';' number of repeats (last line of service)";
601 if((Screen->Width < 1024) || (Screen->Height < 768))
603 ShowMessage(
"Please note that this program works best with a screen resolution of at least 1024 x 768. Please change if possible");
609 WindowState = wsMaximized;
621 Screen->Cursor = TCursor(-2);
650 char *LocalNumericInformation = setlocale(LC_NUMERIC,
"");
652 if(LocalNumericInformation ==
"")
657 struct lconv *conv = &Locale;
663 catch(
const EFOpenError &e)
667 MessageDlg(e.Message +
" - program must terminate", mtError, But, 0);
668 Application->Terminate();
671 catch(
const Exception &e)
675 AnsiString Message =
"A fatal error occurred during the program setup process, the program must terminate. Message = " + e.Message;
676 MessageDlg(Message, mtError, But, 0);
678 Application->Terminate();
689 AnsiString ColourStr =
"", SignalStr =
"";
690 remove((
CurDir +
"\\Config.txt").c_str());
691 std::ofstream ConfigFile((
CurDir +
"\\Config.txt").c_str());
707 ConfigFile << AnsiString(
"Signals=") << SignalStr <<
'\n';
708 ConfigFile << AnsiString(
"BgndCol=") << ColourStr <<
'\n';
709 ConfigFile << AnsiString(
"RLYLocn=") << AnsiString(
LoadRailwayDialog->InitialDir) <<
'\n';
710 ConfigFile << AnsiString(
"TTBLocn=") << AnsiString(
TimetableDialog->InitialDir) <<
'\n';
711 ConfigFile << AnsiString(
"SSNLocn=") << AnsiString(
LoadSessionDialog->InitialDir) <<
'\n';
734 catch(
const Exception &e)
750 catch(
const Exception &e)
769 Screen->Cursor = TCursor(-2);
779 Screen->Cursor = TCursor(-2);
786 catch(
const Exception &e)
803 catch(
const Exception &e)
816 UnicodeString strVersion = L
"N/A";
818 VersionSize = GetFileVersionInfoSizeW(Application->ExeName.c_str(), &VersionHandle);
821 pBuffer =
new BYTE[VersionSize];
823 if(GetFileVersionInfoW(Application->ExeName.c_str(), VersionHandle, VersionSize, pBuffer))
825 VS_FIXEDFILEINFO *fi;
829 if(VerQueryValueW(pBuffer, L
"\\", (
void**)&fi, &buflen))
832 strVersion.sprintf(L
"%d.%d.%d", HIWORD(fi->dwFileVersionMS), LOWORD(fi->dwFileVersionMS), HIWORD(fi->dwFileVersionLS)
841 return L
" v" + strVersion;
857 catch(
const Exception &e)
876 catch(
const Exception &e)
890 if(((TSpeedButton*)Sender)->Down)
899 Screen->Cursor = TCursor(-11);
900 InfoPanel->Caption =
"SELECTING: Filling area with chosen element";
901 bool FillSelectionFlag =
false;
904 UnicodeString MessageStr =
"Click 'Yes' to fill the area with the chosen element or 'No' to abort.\n"
905 "Existing elements won't be overwritten although track can\n"
906 "have platforms and non-station named location elements added.\n\nThis message will not be shown again.";
907 int button = Application->MessageBox(MessageStr.c_str(), L
"", MB_YESNO);
910 FillSelectionFlag =
true;
915 bool TrackLinkingRequiredFlag =
true;
942 Screen->Cursor = TCursor(-2);
953 catch(
const Exception &e)
987 ShowMessage(
"Incomplete track or other error - see inverted element (may be behind this message)");
998 ShowMessage(
"Unable to set any track links");
1011 ShowMessage(
"Successful Completion");
1027 catch(
const Exception &e)
1048 catch(
const Exception &e)
1067 catch(
const Exception &e)
1086 catch(
const Exception &e)
1105 TFont *TempFont =
new TFont;
1113 TempText.
Font = DisplayFont;
1120 else if(Key ==
'\x1B')
1126 catch(
const Exception &e)
1145 catch(
const Exception &e)
1160 ShowMessage(
"Error, location name being entered without an entry in LNPendingList");
1180 Screen->Cursor = TCursor(-11);
1182 AnsiString ExistingName;
1190 UnicodeString MessageStr = UnicodeString(
"Another location named '") +
LocationNameTextBox->Text +
1191 UnicodeString(
"' already exists. If you continue its name will be erased. Do you wish to continue?");
1192 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
1196 Screen->Cursor = TCursor(-2);
1207 bool UseExistingPosition =
false;
1214 if(ExistingName !=
"")
1217 UseExistingPosition =
true;
1220 Screen->Cursor = TCursor(-2);
1234 bool UseExistingPosition =
false;
1236 UseExistingPosition =
true;
1239 Screen->Cursor = TCursor(-2);
1251 LocStr = LocStr.Trim();
1260 if((LocStr !=
"") && (LocStr[1] >=
'0') && (LocStr[1] <=
'9'))
1262 Screen->Cursor = TCursor(-2);
1263 ShowMessage(
"Location name can't begin with a number");
1271 if(LocStr.Length() > 50)
1273 Screen->Cursor = TCursor(-2);
1274 ShowMessage(
"Location name too long, 50 characters maximum");
1282 for(
int x = 1; x <= LocStr.Length(); x++)
1284 char Ch = LocStr[x];
1285 if((Ch !=
' ') && (Ch !=
'&') && (Ch !=
'(') && (Ch !=
')') && (Ch !=
':') && (Ch != 39) && (Ch !=
'.') && (Ch !=
'-') && (Ch !=
'+') &&
1286 (Ch !=
'/') && ((Ch <
'0') || (Ch >
'9')) && ((Ch <
'A') || (Ch >
'Z')) && ((Ch <
'a') || (Ch >
'z')))
1288 Screen->Cursor = TCursor(-2);
1290 "Location name contains one or more invalid characters, must be alphanumeric, brackets, space, full stop, colon, inverted comma, '-', '+', '/' or '&&'");
1301 Screen->Cursor = TCursor(-2);
1302 ShowMessage(
"Location name cannot be 'cdt', this name would interfere with the timetable");
1313 bool UseExistingPosition =
false;
1314 if(ExistingName !=
"")
1317 UseExistingPosition =
true;
1320 Screen->Cursor = TCursor(-2);
1329 Screen->Cursor = TCursor(-2);
1332 catch(
const Exception &e)
1353 catch(
const Exception &e)
1366 int Dist = 0, SpeedLimit = 0;
1369 DistanceStr =
"No change";
1372 SpeedStr =
"No change";
1375 if(DistanceStr ==
"No change")
1377 if(SpeedStr ==
"No change")
1387 if(((Dist != -1) && (DistanceStr.Length() > 6)) || ((SpeedLimit != -1) && (SpeedStr.Length() > 6)))
1389 ShowMessage(
"One or more entries too long");
1393 if((DistanceStr ==
"") || (SpeedStr ==
""))
1395 ShowMessage(
"One or more entries blank");
1401 for(
int x = 1; x <= DistanceStr.Length(); x++)
1403 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1405 ShowMessage(
"Track length value must be a positive whole number, or blank for no change");
1413 for(
int x = 1; x <= DistanceStr.Length(); x++)
1415 if((DistanceStr[x] <
'0') || (DistanceStr[x] >
'9'))
1417 ShowMessage(
"Distance must be a positive whole number");
1425 for(
int x = 1; x <= SpeedStr.Length(); x++)
1427 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1429 ShowMessage(
"Speed limit must be a positive whole number, or blank for no change");
1437 for(
int x = 1; x <= SpeedStr.Length(); x++)
1439 if((SpeedStr[x] <
'0') || (SpeedStr[x] >
'9'))
1441 ShowMessage(
"Speed limit must be a positive whole number, or 'Mixed'");
1448 Dist = DistanceStr.ToInt();
1449 if(SpeedLimit != -1)
1450 SpeedLimit = SpeedStr.ToInt();
1458 if(((Dist != -1) && (Dist < 20)) || ((SpeedLimit != -1) && (SpeedLimit < 10)) || ((SpeedLimit != -1) && (SpeedLimit >
TTrain::MaximumSpeedLimit)))
1461 ShowMessage(
"Lengths must be 20m or more, and speeds must be between 10km/h and 400km/h");
1474 bool NamedLocPresent =
false;
1477 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1479 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1482 NamedLocPresent =
true;
1486 if(NamedLocPresent && (Dist < 50))
1488 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
1491 if(NamedLocPresent && (Dist > 200))
1493 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
1496 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1498 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1535 catch(
const Exception &e)
1558 catch(
const Exception &e)
1570 TMsgDlgButtons Buttons;
1571 Buttons << mbYes << mbNo;
1572 if(MessageDlg(
"This will reset the selected elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1590 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
1592 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
1646 throw Exception(
"Error, XLinkPos > 1 in SetOneDefaultTrackLength at " + AnsiString(TrackElement.
HLoc) +
" & " +
1647 AnsiString(TrackElement.
VLoc));
1663 catch(
const Exception &e)
1675 TMsgDlgButtons Buttons;
1676 Buttons << mbYes << mbNo;
1677 if(MessageDlg(
"This will reset ALL track elements to default lengths & speed limits. Proceed?", mtWarning, Buttons, 0) == mrNo)
1698 catch(
const Exception &e)
1726 bool GraphicFoundInVector =
false;
1727 for(TTrack::TUserGraphicVector::iterator UGVIt =
Track->
UserGraphicVector.begin(); UGVIt < Track->UserGraphicVector.end(); UGVIt++)
1729 if(UGMIt->first == UGVIt->FileName)
1731 GraphicFoundInVector =
true;
1735 if(!GraphicFoundInVector)
1737 delete UGMIt->second;
1753 catch(
const Exception &e)
1793 catch(
const Exception &e)
1832 catch(
const Exception &e)
1856 catch(
const Exception &e)
1882 catch(
const Exception &e)
1901 catch(
const Exception &e)
1916 ShowMessage(
"No preferred direction selection");
1920 Screen->Cursor = TCursor(-11);
1925 Screen->Cursor = TCursor(-2);
1928 catch(
const Exception &e)
1941 TMsgDlgButtons Buttons;
1942 Buttons << mbYes << mbNo;
1943 if(MessageDlg(
"Do you really want to clear all preferred directions?", mtWarning, Buttons, 0) == mrNo)
1959 catch(
const Exception &e)
1974 Screen->Cursor = TCursor(-11);
1983 Screen->Cursor = TCursor(-2);
1986 catch(
const Exception &e)
2004 catch(
const Exception &e)
2025 catch(
const Exception &e)
2050 catch(
const Exception &e)
2074 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2076 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
2084 catch(
const Exception &e)
2108 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
2110 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
2118 catch(
const Exception &e)
2148 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2150 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
2158 catch(
const Exception &e)
2173 InfoPanel->Caption =
"ROUTE CANCELLING: Right click on truncate element, first element to cancel (anywhere else to skip)";
2180 catch(
const Exception &e)
2207 catch(
const Exception &e)
2222 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
2225 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
2263 catch(
const Exception &e)
2305 catch(
const Exception &e)
2317 Screen->Cursor = TCursor(-11);
2318 std::ifstream VecFile(LoadFileName.c_str());
2319 if(!(VecFile.fail()))
2324 bool GraphicsFollow =
false;
2343 TFont *TempFont =
new TFont;
2344 TempFont->Style.Clear();
2345 TempFont->Name =
"MS Sans Serif";
2346 TempFont->Size = 10;
2348 TempFont->Charset = (TFontCharset)(0);
2357 if((LeftExcess > 0) && (RightExcess > 0))
2359 else if((LeftExcess > 0) && (RightExcess <= 0))
2362 else if((LeftExcess <= 0) && (RightExcess > 0))
2370 if((TopExcess > 0) && (BotExcess > 0))
2372 else if((TopExcess > 0) && (BotExcess <= 0))
2375 else if((TopExcess <= 0) && (BotExcess > 0))
2388 if((LastChar ==
'y') || (LastChar ==
'Y'))
2392 ShowMessage(
"Railway not ready for operation so unable to load as a .rly file. Loading as a new railway under development");
2399 Screen->Cursor = TCursor(-2);
2432 ShowMessage(
"File open failed prior to load");
2433 Screen->Cursor = TCursor(-2);
2436 ShowMessage(
"File integrity check failed - unable to load");
2451 Screen->Cursor = TCursor(-11);
2453 if(!(VecFile.fail()))
2480 ShowMessage(
"File open failed prior to save");
2481 Screen->Cursor = TCursor(-2);
2486 catch(
const Exception &e)
2502 catch(
const Exception &e)
2518 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2522 Screen->Cursor = TCursor(-11);
2525 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2529 AnsiString ShortName =
"";
2530 for(
int x = ImageFileName.Length(); x > 0; x--)
2532 if(ImageFileName[x] ==
'\\')
2534 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2538 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2539 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2540 RailwayImage->PixelFormat = pf8bit;
2546 RailwayImage->Width = HPosMax - HPosMin;
2547 RailwayImage->Height = VPosMax - VPosMin;
2555 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2556 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2557 if(NewWidth > RailwayImage->Width)
2559 RailwayImage->Width = NewWidth;
2561 if(NewHeight > RailwayImage->Height)
2563 RailwayImage->Height = NewHeight;
2568 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2569 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2570 RailwayImage->Canvas->FillRect(Rect);
2578 RailwayImage->SaveToFile(ImageFileName);
2579 delete RailwayImage;
2582 Screen->Cursor = TCursor(-2);
2585 catch(
const Exception &e)
2587 if(e.Message.Pos(
"torage") > 0)
2589 Screen->Cursor = TCursor(-2);
2590 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2591 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2610 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2614 Screen->Cursor = TCursor(-11);
2617 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2621 AnsiString ShortName =
"";
2622 for(
int x = ImageFileName.Length(); x > 0; x--)
2624 if(ImageFileName[x] ==
'\\')
2626 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2630 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2631 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2632 RailwayImage->PixelFormat = pf8bit;
2637 RailwayImage->Width = HPosMax - HPosMin;
2638 RailwayImage->Height = VPosMax - VPosMin;
2646 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2647 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2648 if(NewWidth > RailwayImage->Width)
2650 RailwayImage->Width = NewWidth;
2652 if(NewHeight > RailwayImage->Height)
2654 RailwayImage->Height = NewHeight;
2659 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2660 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2661 RailwayImage->Canvas->FillRect(Rect);
2664 for(
int x = 0; x < ((RailwayImage->Width) / 16); x++)
2666 for(
int y = 0; y < ((RailwayImage->Height) / 16); y++)
2676 RailwayImage->SaveToFile(ImageFileName);
2677 delete RailwayImage;
2680 Screen->Cursor = TCursor(-2);
2683 catch(
const Exception &e)
2685 if(e.Message.Pos(
"torage") > 0)
2687 Screen->Cursor = TCursor(-2);
2688 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2689 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2707 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2711 Screen->Cursor = TCursor(-11);
2714 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2718 AnsiString ShortName =
"";
2719 for(
int x = ImageFileName.Length(); x > 0; x--)
2721 if(ImageFileName[x] ==
'\\')
2723 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2727 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2728 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2729 RailwayImage->PixelFormat = pf8bit;
2734 RailwayImage->Width = HPosMax - HPosMin;
2735 RailwayImage->Height = VPosMax - VPosMin;
2743 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2744 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2745 if(NewWidth > RailwayImage->Width)
2747 RailwayImage->Width = NewWidth;
2749 if(NewHeight > RailwayImage->Height)
2751 RailwayImage->Height = NewHeight;
2756 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2757 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2758 RailwayImage->Canvas->FillRect(Rect);
2766 RailwayImage->SaveToFile(ImageFileName);
2767 delete RailwayImage;
2770 Screen->Cursor = TCursor(-2);
2773 catch(
const Exception &e)
2775 if(e.Message.Pos(
"torage") > 0)
2777 Screen->Cursor = TCursor(-2);
2778 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2779 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2797 ShowMessage(
"Failed to find folder " +
IMAGE_DIR_NAME +
" in the folder where 'railway.exe' resides. Image can't be saved");
2801 Screen->Cursor = TCursor(-11);
2806 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
2807 AnsiString ImageFileName = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
2812 AnsiString ShortName =
"";
2813 for(
int x = ImageFileName.Length(); x > 0; x--)
2815 if(ImageFileName[x] ==
'\\')
2817 ShortName = ImageFileName.SubString(x + 1, ImageFileName.Length() - x - 4);
2821 ShowMessage(
"A bitmap file named " + ShortName +
" will be created in the Images folder");
2822 Graphics::TBitmap *RailwayImage =
new Graphics::TBitmap;
2823 RailwayImage->PixelFormat = pf8bit;
2828 RailwayImage->Width = HPosMax - HPosMin;
2829 RailwayImage->Height = VPosMax - VPosMin;
2837 int NewWidth = (TextPtr->HPos - HPosMin) + (abs(TextPtr->Font->Height) * TextPtr->TextString.Length() * 0.7);
2838 int NewHeight = (TextPtr->VPos - VPosMin) + (abs(TextPtr->Font->Height) * 1.5);
2839 if(NewWidth > RailwayImage->Width)
2841 RailwayImage->Width = NewWidth;
2843 if(NewHeight > RailwayImage->Height)
2845 RailwayImage->Height = NewHeight;
2850 RailwayImage->Canvas->Brush->Color =
clB5G5R5;
2851 TRect Rect(0, 0, RailwayImage->Width, RailwayImage->Height);
2852 RailwayImage->Canvas->FillRect(Rect);
2867 bool BreakFlag =
false;
2893 RailwayImage->SaveToFile(ImageFileName);
2894 delete RailwayImage;
2897 Screen->Cursor = TCursor(-2);
2900 catch(
const Exception &e)
2902 if(e.Message.Pos(
"torage") > 0)
2904 Screen->Cursor = TCursor(-2);
2905 UnicodeString MessageStr =
"Insufficient memory available to store this image";
2906 Application->MessageBox(MessageStr.c_str(), L
"", MB_OK | MB_ICONWARNING);
2934 Screen->Cursor = TCursor(-11);
2936 if(!(VecFile.fail()))
2963 ShowMessage(
"Railway failed to save - can't open file");
2964 Screen->Cursor = TCursor(-2);
2968 catch(
const Exception &e)
2982 catch(
const Exception &e)
3002 catch(
const Exception &e)
3017 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
3025 Screen->Cursor = TCursor(-2);
3028 catch(
const Exception &e)
3088 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3105 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3106 ActiveTrackElementNameMapEntry.second = 0;
3156 catch(
const Exception &e)
3205 if(TTBLFile.is_open())
3209 while(!TTBLFile.eof())
3212 if((c < 32) && (c != 13) && (c != 10) && (c !=
'\0'))
3214 ShowMessage(
"Timetable file is empty or contains non-ascii characters, codes must be between 20 and 127, or CR or LF");
3224 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3231 if(TTBLFile.is_open())
3240 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
3253 char *TimetableEntryString =
new char[10000];
3256 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
3257 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
3262 AnsiString OneLine(TimetableEntryString);
3266 delete TimetableEntryString;
3271 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
3307 ActiveTrackElementNameMapEntry.first =
Track->
TrackVector.at(x).ActiveTrackElementName;
3308 ActiveTrackElementNameMapEntry.second = 0;
3333 catch(
const Exception &e)
3352 InfoPanel->Caption =
"Timetable mode: editor hidden";
3359 ShowHideTTButton->Hint =
"Hide the timetable editor to see the railway Shift H";
3364 catch(
const Exception &e)
3403 catch(
const Exception &e)
3442 catch(
const Exception &e)
3462 catch(
const Exception &e)
3475 bool ValidFlag =
true;
3494 TDateTime DummyTime;
3512 ShowMessage(
"One or more times excessive, not permitted to exceed 95 hours");
3516 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3518 MinsStr =
"0" + MinsStr;
3520 HrsStr =
"0" + HrsStr;
3523 NewString += HrsStr +
':' + MinsStr;
3540 catch(
const Exception &e)
3553 bool ValidFlag =
true;
3572 TDateTime DummyTime;
3590 ShowMessage(
"One or more times are now before 00:00, this is not permitted");
3594 AnsiString MinsStr = AnsiString(Mins), HrsStr = AnsiString(Hrs);
3596 MinsStr =
"0" + MinsStr;
3598 HrsStr =
"0" + HrsStr;
3601 NewString += HrsStr +
':' + MinsStr;
3617 catch(
const Exception &e)
3655 catch(
const Exception &e)
3701 if(OldVectorPos == 0)
3729 catch(
const Exception &e)
3788 catch(
const Exception &e)
3806 UnicodeString MessageStr =
"Are you sure this entry should be deleted?";
3807 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
3839 if(OldVectorPos == 0)
3867 catch(
const Exception &e)
3888 AnsiString TempStr =
"";
3889 bool ActiveLine =
false;
3914 while(TempStr[TempStr.Length()] ==
',')
3916 TempStr = TempStr.SubString(1, TempStr.Length() - 1);
3945 (*TTCurrentEntryPtr) = TempStr;
4015 catch(
const Exception &e)
4030 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4034 std::ofstream TTBLFile;
4069 if(TTBLFile.is_open())
4073 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4080 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4086 catch(
const Exception &e)
4101 ShowMessage(
"Timetable is empty, can't save an empty timetable");
4105 std::ofstream TTBLFile;
4114 for(
int x =
SaveTTDialog->FileName.Length(); x > 0; x--)
4132 if(TTBLFile.is_open())
4136 TTBLFile << (*TEVPtr).c_str() <<
'\0';
4143 ShowMessage(
CreateEditTTFileName +
" failed to open, ensure not already open in another application");
4149 catch(
const Exception &e)
4163 bool EndOfFile =
false;
4164 bool FinalCallFalse =
false;
4165 bool GiveMessagesTrue =
true;
4166 bool CheckLocationsExistInRailway =
false;
4168 CheckLocationsExistInRailway =
true;
4174 "The basic syntax seems OK but this check is very limited. Other aspects can only be checked by validating the whole timetable with the appropriate railway (.rly) loaded");
4180 catch(
const Exception &e)
4208 bool CheckLocationsExistInRailwayTrue =
true;
4211 Screen->Cursor = TCursor(-11);
4213 if(TTBLFile.is_open())
4217 ShowMessage(
"Timetable integrity OK");
4224 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4226 Screen->Cursor = TCursor(-2);
4236 catch(
const Exception &e)
4260 AnsiString TempStr = *
TEVPtr;
4298 catch(
const Exception &e)
4322 AnsiString TempStr = *
TEVPtr;
4360 catch(
const Exception &e)
4397 catch(
const Exception &e)
4412 UnicodeString MessageStr =
"All changes to the timetable will be lost - proceed?";
4413 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4424 if(TTBLFile.is_open())
4441 char *TimetableEntryString =
new char[10000];
4444 TTBLFile.getline(TimetableEntryString, 10000,
'\0');
4445 if(TTBLFile.eof() && (TimetableEntryString[0] ==
'\0'))
4450 AnsiString OneLine(TimetableEntryString);
4454 delete TimetableEntryString;
4459 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
4480 catch(
const Exception &e)
4495 ShowMessage(
"Failed to find folder " +
FORMATTEDTT_DIR_NAME +
" in the folder where 'railway.exe' resides. Timetable can't be exported");
4514 Screen->Cursor = TCursor(-2);
4519 catch(
const Exception &e)
4552 catch(
const Exception &e)
4567 UnicodeString MessageStr =
"The timetable has changed.\n\nAre you sure you want to exit without saving it?";
4568 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
4584 catch(
const Exception &e)
4612 catch(
const Exception &e)
4637 catch(
const Exception &e)
4655 catch(
const Exception &e)
4678 catch(
const Exception &e)
4687 TShiftState Shift,
int X,
int Y)
4731 catch(
const Exception &e)
4760 if((TopPos + (Y / 13)) >=
OAListBox->Items->Count)
4768 std::advance(OACurrentEntryPtr, ((Y / 13) + TopPos));
4772 int TrackVectorPosition;
4773 int TrainIDorTVPos = OACurrentEntryPtr->second.second;
4774 if(TrainIDorTVPos >= 0)
4790 TrackVectorPosition = -(TrainIDorTVPos + 1);
4805 TPoint MainScreenPoint(ScreenPosH + 8, ScreenPosV + 8);
4806 TPoint CursPos =
MainScreen->ClientToScreen(MainScreenPoint);
4807 Mouse->CursorPos = CursPos;
4810 catch(
const Exception &e)
4822 PreStartTime, ActiveSegment, PostEnd} Segment;
4835 Segment = PreStartTime;
4838 if(Segment == PreStartTime)
4845 Segment = ActiveSegment;
4856 AnsiString CurrentStr = *
TEVPtr;
4857 if(CurrentStr !=
"")
4859 CurrentStr = CurrentStr.SubString(1, 10);
4860 for(
int x = 1; x < CurrentStr.Length(); x++)
4862 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4864 CurrentStr = CurrentStr.SubString(1, (x - 1));
4873 if(Segment == ActiveSegment)
4888 AnsiString Entry = *
TEVPtr;
4893 int SCPos = Entry.Pos(
';');
4894 int CPos = Entry.Pos(
',');
4901 if((CPos == 0) && (SCPos == 0))
4903 Entry = Entry.SubString(1, 12);
4905 else if((CPos > 0) && (SCPos > 0) && (CPos < SCPos))
4907 Entry = Entry.SubString(1, CPos - 1);
4909 else if((CPos > 0) && (SCPos > 0) && (CPos > SCPos))
4911 Entry = Entry.SubString(1, SCPos - 1);
4913 else if((CPos > 0) && (SCPos == 0))
4915 Entry = Entry.SubString(1, CPos - 1);
4919 Entry = Entry.SubString(1, SCPos - 1);
4932 if(Segment == PostEnd)
4940 AnsiString CurrentStr = *
TEVPtr;
4941 if(CurrentStr !=
"")
4943 CurrentStr = CurrentStr.SubString(1, 10);
4944 for(
int x = 1; x < CurrentStr.Length(); x++)
4946 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
4948 CurrentStr = CurrentStr.SubString(1, (x - 1));
4979 UnicodeString MessageStr =
4980 "If you wish to preserve the original order don't make any changes whilst in alphabetical order.\n\nIn that case use alphabetical order to find the service required, click it to display it, then revert to the original order where the same service will be displayed and can be changed.";
4981 Application->MessageBox(MessageStr.c_str(), L
"Please Note:", MB_OK | MB_ICONWARNING);
4994 std::sort(SortStart, SortEnd);
4996 bool CurrentEntryChanged =
false;
5002 CurrentEntryChanged =
true;
5005 if(!CurrentEntryChanged)
5010 AZOrderButton->Hint = AnsiString(
"Arrange services in original order Toggle with Shift+ Z");
5016 UnicodeString MessageStr =
5017 "Reverting to the original order will discard any changes made whilst in alphabetical order.\n\nTo preserve the changes click 'No', then save the timetable or use 'save as' if you wish to keep the original timetable.\n\nDo you wish to proceed?";
5018 int button = Application->MessageBox(MessageStr.c_str(), L
"Warning!", MB_YESNO | MB_ICONWARNING);
5032 bool CurrentEntryChanged =
false;
5038 CurrentEntryChanged =
true;
5041 if(!CurrentEntryChanged)
5046 AZOrderButton->Hint = AnsiString(
"Arrange services in alphabetical order Toggle with Shift+ Z");
5055 catch(
const Exception &e)
5066 AnsiString OutStr =
"";
5069 while(x < ConvStr.Length())
5071 if((ConvStr[x] ==
'\r') && (ConvStr[x + 1] ==
'\n'))
5079 OutStr += ConvStr[x];
5083 if(x == ConvStr.Length())
5084 OutStr += ConvStr[x];
5089 while(OutStr[OutStr.Length()] ==
',')
5091 OutStr = OutStr.SubString(1, OutStr.Length() - 1);
5161 InfoPanel->Caption =
"Select option or change entry";
5175 bool ValidFlag =
true;
5176 for(
int x = 1; x <= AnsiAddSubText.Length(); x++)
5178 if((AnsiAddSubText[x] >
'9') || (AnsiAddSubText[x] <
'0'))
5186 if(AnsiAddSubText.ToInt() != 0)
5258 bool ServiceEntry =
true;
5263 bool ServiceEntry =
false;
5275 InfoPanel->Caption =
"Add or change entry then save it, or cancel";
5285 AnsiString((
short)ServiceEntry));
5292 int CommaPos = Data.Pos(
',');
5293 if((CommaPos == 0) && (Data !=
""))
5295 CommaPos = Data.Length() + 1;
5298 if(Data.Length() <= CommaPos)
5300 Data = Data.SubString(CommaPos + 1, Data.Length() - CommaPos);
5337 if(CurrentStr !=
"")
5339 for(
int x = 1; x < CurrentStr.Length(); x++)
5341 if((CurrentStr[x] < 32) || (CurrentStr[1] > 126))
5343 CurrentStr = CurrentStr.SubString(1, (x - 1));
5368 TDateTime DummyTime;
5369 bool TimesPresent =
false;
5377 TimesPresent =
true;
5384 return TimesPresent;
5398 UnicodeString MessageStr =
5399 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
5400 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5409 UnicodeString MessageStr =
"The railway has changed, exit without saving?";
5410 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
5422 Application->Terminate();
5424 catch(
const Exception &e)
5447 catch(
const Exception &e)
5470 catch(
const Exception &e)
5493 catch(
const Exception &e)
5552 catch(
const Exception &e)
5570 catch(
const Exception &e)
5589 catch(
const Exception &e)
5624 catch(
const Exception &e)
5635 TrainController->
LogEvent(
"MainScreenMouseDown2," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
5637 "," + AnsiString(Y));
5648 int NoOffsetX, NoOffsetY;
5650 if(Button == mbRight)
5654 AnsiString Text =
"";
5661 Screen->Cursor = TCursor(-22);
5712 bool TrackEraseSuccessfulFlag;
5713 int ErasedTrackVectorPosition;
5714 Screen->Cursor = TCursor(-11);
5716 if(TrackEraseSuccessfulFlag)
5718 if(ErasedTrackVectorPosition > -1)
5749 Screen->Cursor = TCursor(-2);
5757 bool LeadingPointsAtLastElement =
false;
5772 if(!LeadingPointsAtLastElement)
5777 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
5792 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, continue or truncate";
5869 if((TrainID01 > -1) && (TrainID23 > -1))
5919 AnsiString LocName =
"";
5924 if((LocName ==
"") && (Train.
MidElement > -1))
6040 Screen->Cursor = TCursor(-11);
6051 Screen->Cursor = TCursor(-2);
6118 Screen->Cursor = TCursor(-11);
6120 bool TrackLinkingRequiredFlag;
6122 TSpeedButton *TempSpeedButton = 0;
6130 bool InternalChecks =
true;
6136 if(TrackLinkingRequiredFlag)
6165 Screen->Cursor = TCursor(-2);
6179 NewGI.
Width = UGMIt->second->Width;
6180 NewGI.
Height = UGMIt->second->Height;
6205 AnsiString NameString;
6215 unsigned int ValidPosition;
6226 ValidElement = InactiveTrackElement1;
6227 ValidPosition = InactivePair.first;
6232 ValidElement = InactiveTrackElement2;
6233 ValidPosition = InactivePair.second;
6244 InfoPanel->Caption =
"NAMING LOCATIONS: Enter name, 'Carriage Return' to accept, 'Escape' to quit";
6275 bool FinishElement =
false, LeadingPointsAtLastElement =
false;
6276 Screen->Cursor = TCursor(-11);
6290 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values (overall length), or right click to cancel/truncate";
6300 Screen->Cursor = TCursor(-2);
6306 if(!LeadingPointsAtLastElement)
6311 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
6328 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Can't end on leading points, need to continue or truncate";
6343 Screen->Cursor = TCursor(-2);
6348 Screen->Cursor = TCursor(-2);
6365 InfoPanel->Caption =
"CONNECTING GAPS: Connecting element selected";
6377 ShowMessage(
"All gaps set");
6405 int TrueX = 0, TrueY = 0;
6406 AnsiString ExistingText =
"";
6408 TFont *ExistingTextFont =
new TFont;
6409 int ExistingTextHPos = 0, ExistingTextVPos = 0;
6415 if((TrueX >= TextPtr->HPos) && (TrueX < (TextPtr->HPos + abs(TextPtr->Font->Height))) && (TrueY >= TextPtr->VPos) && (TrueY <
6416 (TextPtr->VPos + abs(TextPtr->Font->Height))))
6418 ExistingText = TextPtr->TextString;
6419 ExistingTextFont->Assign(TextPtr->Font);
6420 ExistingTextHPos = TextPtr->HPos;
6421 ExistingTextVPos = TextPtr->VPos;
6433 TextBox->Font->Assign(ExistingTextFont);
6435 Text_X = ExistingTextHPos;
6436 Text_Y = ExistingTextVPos;
6451 TextBox->Text =
"New Text: CR=end, ESC=quit";
6454 delete ExistingTextFont;
6546 Screen->Cursor = TCursor(-11);
6555 ShowMessage(
"Preferred direction added");
6559 Screen->Cursor = TCursor(-2);
6578 Screen->Cursor = TCursor(-2);
6582 Screen->Cursor = TCursor(-2);
6679 AnsiString(PDE.
VLoc));
6692 bool PointsChanged =
false;
6693 IDInt ReqPosRouteID(-1);
6695 bool CallonTrue =
true;
6696 bool ConsecSignalsRouteFalse =
false;
6705 CallonTrue, ReqPosRouteID, PointsChanged))
6747 float TempSpeedVal = 1;
6815 int DivergingPosition = TrackElement.
Conn[3];
6817 DivergingPosition)))
6845 bool TrainPresent =
false;
6849 int BDVectorPos = -1;
6857 TDateTime TempExcessLCDownTime;
6866 if(TempExcessLCDownTime > TDateTime(0))
6895 AnsiString Message = AnsiString(
"This will open the level crossing manually (it will show in green).\n\nA manually opened"
6896 " level crossing must be manually closed, and as soon as possible to avoid time penalties.\n\n"
6897 "This message will not be shown again.");
6936 InfoPanel->Caption =
"PRE-START: Select next route location";
6938 InfoPanel->Caption =
"OPERATING: Select next route location";
6950 bool CallonFalse =
false;
6957 InfoPanel->Caption =
"PRE-START: Select next route location";
6959 InfoPanel->Caption =
"OPERATING: Select next route location";
6977 Screen->Cursor = TCursor(-11);
6979 bool PointsChanged =
false;
6989 float TempSpeedVal = 1;
6994 else if(PointsChanged)
7005 Screen->Cursor = TCursor(-2);
7013 bool CallonFalse =
false;
7019 float TempSpeedVal = 1;
7024 else if(PointsChanged)
7038 Screen->Cursor = TCursor(-2);
7047 catch(
const Exception &e)
7061 TrainController->
LogEvent(
"MainScreenMouseDown3," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7063 "," + AnsiString(Y));
7064 if(Button != mbLeft)
7070 Screen->Cursor = TCursor(-22);
7076 int HRounding, VRounding;
7127 else if(TempLevel2OperMode ==
Operating)
7130 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
7134 else if(TempLevel2OperMode ==
Paused)
7137 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7143 else if(TempLevel2OperMode ==
PreStart)
7146 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
7157 catch(
const Exception &e)
7247 if(CurrentHLoc >= StartHLoc)
7251 if(CurrentVLoc >= StartVLoc)
7263 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7277 if(CurrentHLoc >= StartHLoc)
7281 if(CurrentVLoc >= StartVLoc)
7293 TRect TempRect(StartHLoc, StartVLoc, CurrentHLoc, CurrentVLoc);
7352 catch(
const Exception &e)
7388 TrainController->
LogEvent(
"MainScreenMouseUp," + AnsiString(Button) +
"," + AnsiString(X) +
"," + AnsiString(Y));
7391 Screen->Cursor = TCursor(-2);
7395 Screen->Cursor = TCursor(-11);
7400 if(EndHLoc >= StartHLoc)
7404 if(EndVLoc >= StartVLoc)
7408 if(StartHLoc >= EndHLoc)
7418 if(StartVLoc >= EndVLoc)
7444 Screen->Cursor = TCursor(-2);
7510 if(IATVecPair.second != IATVecPair.first)
7528 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
7536 bool SelectVectorNamedElement =
false;
7537 AnsiString SelectTextString;
7542 SelectVectorNamedElement =
true;
7546 if(SelectVectorNamedElement)
7548 SelectTextString =
"##**" + TextPtr->TextString;
7552 SelectTextString = TextPtr->TextString;
7554 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
7563 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
7566 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) &&
7567 (UserGraphicPtr->VPos >= LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
7580 Screen->Cursor = TCursor(-2);
7586 Screen->Cursor = TCursor(-11);
7592 if(EndHLoc >= StartHLoc)
7596 if(EndVLoc >= StartVLoc)
7600 if(StartHLoc >= EndHLoc)
7610 if(StartVLoc >= EndVLoc)
7635 Screen->Cursor = TCursor(-2);
7664 Screen->Cursor = TCursor(-2);
7690 catch(
const Exception &e)
7723 throw Exception(
"Warning - Utilities->CallLog contains more than 50 items");
7750 catch(
const Exception &e)
7830 if(
WholeRailwayMoving && (GetAsyncKeyState(VK_LBUTTON) >= 0) && (GetAsyncKeyState(VK_RBUTTON) >= 0))
7833 Screen->Cursor = TCursor(-2);
7860 bool TrainPresent =
false;
7876 TDateTime TempExcessLCDownTime;
7885 if(TempExcessLCDownTime > TDateTime(0))
7914 bool ElementRemovedFlag =
false;
7931 int RouteNumber1, RouteNumber2, TrainID;
7938 ElementRemovedFlag =
true;
7954 bool WH1 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog1->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog1->Width +
OutputLog1->Left))
7957 bool WH2 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog2->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog2->Width +
OutputLog2->Left))
7960 bool WH3 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog3->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog3->Width +
OutputLog3->Left))
7963 bool WH4 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog4->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog4->Width +
OutputLog4->Left))
7966 bool WH5 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog5->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog5->Width +
OutputLog5->Left))
7969 bool WH6 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog6->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog6->Width +
OutputLog6->Left))
7972 bool WH7 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog7->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog7->Width +
OutputLog7->Left))
7975 bool WH8 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog8->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog8->Width +
OutputLog8->Left))
7978 bool WH9 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog9->Left) && (Mouse->CursorPos.x < (ClientOrigin.x +
OutputLog9->Width +
OutputLog9->Left))
7981 bool WH10 = (Mouse->CursorPos.x >= ClientOrigin.x +
OutputLog10->Left) &&
7985 if(WH1 || WH2 || WH3 || WH4 || WH5 || WH6 || WH7 || WH8 || WH9 || WH10)
8006 AnsiString Type[15] =
8007 {
"Simple",
"Crossover",
"Points",
"Buffers",
"Bridge",
"SignalPost",
"Continuation",
"Platform",
"GapJump",
"FootCrossing",
"Unused",
"Concourse",
8008 "Parapet",
"NamedNonStationLocation",
"Erase"};
8010 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
8011 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
8013 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
8018 DevelopmentPanel->Caption = MouseStr +
"; TVPos: " + AnsiString(Position) +
"; H: " + AnsiString(HLoc) +
"; V: " + AnsiString(VLoc) +
8019 "; SpTg: " + AnsiString(TrackElement.
SpeedTag) +
"; Type: " + Type[TrackElement.
TrackType] +
"; Att: " + AnsiString(TrackElement.
Attribute)
8037 if((GetKeyState(VK_LBUTTON) >= 0) && (GetKeyState(VK_RBUTTON) >= 0) && (
TTCurrentEntryPtr > 0))
8168 Screen->Cursor = TCursor(-11);
8324 int RouteStartVecPos;
8334 if(FoundFlag && (RouteStartVecPos > -1))
8350 catch(
const Exception &e)
8368 InfoPanel->Caption =
"CALLING ON: Select signal for call on";
8382 catch(
const Exception &e)
8396 Screen->Cursor = TCursor(-11);
8438 Screen->Cursor = TCursor(-2);
8441 catch(
const Exception &e)
8455 Screen->Cursor = TCursor(-11);
8497 Screen->Cursor = TCursor(-2);
8500 catch(
const Exception &e)
8514 Screen->Cursor = TCursor(-11);
8557 Screen->Cursor = TCursor(-2);
8560 catch(
const Exception &e)
8574 Screen->Cursor = TCursor(-11);
8616 Screen->Cursor = TCursor(-2);
8619 catch(
const Exception &e)
8633 Screen->Cursor = TCursor(-11);
8670 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
8677 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8686 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
8713 if((LeftExcess > 0) && (RightExcess > 0))
8715 else if((LeftExcess > 0) && (RightExcess <= 0))
8718 else if((LeftExcess <= 0) && (RightExcess > 0))
8726 if((TopExcess > 0) && (BotExcess > 0))
8728 else if((TopExcess > 0) && (BotExcess <= 0))
8731 else if((TopExcess <= 0) && (BotExcess > 0))
8741 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomIn");
8743 Screen->Cursor = TCursor(-2);
8747 catch(
const Exception &e)
8761 Screen->Cursor = TCursor(-11);
8784 Screen->Cursor = TCursor(-2);
8788 catch(
const Exception &e)
8816 catch(
const Exception &e)
8832 catch(
const Exception &e)
8853 ShowMessage(
"Please be aware when pasting that anything inside the pasted area will be overwritten.\n\nThis warning will not be shown again.");
8864 catch(
const Exception &e)
8887 TRect NewSelectRect(TLHCH, TLHCV, BRHCH, BRHCV);
8920 catch(
const Exception &e)
8939 catch(
const Exception &e)
8958 catch(
const Exception &e)
9006 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9014 catch(
const Exception &e)
9062 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9064 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9074 catch(
const Exception &e)
9127 int MidVPosAfterFlip = ((VerSum * 16) + 15) - MidVPosBeforeFlip;
9139 int MidHPosAfterMirror = ((HorSum * 16) + 15) - MidHPosBeforeMirror;
9141 if(LeftPosAfterMirror < (
SelectRect.left * 16))
9153 catch(
const Exception &e)
9166 Screen->Cursor = TCursor(-11);
9183 int button = Application->MessageBox
9184 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9185 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9186 if(button == IDCANCEL)
9194 Screen->Cursor = TCursor(-2);
9231 if(IATVecPair.second != IATVecPair.first)
9249 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9256 bool SelectVectorNamedElement =
false;
9257 AnsiString SelectTextString;
9262 SelectVectorNamedElement =
true;
9266 if(SelectVectorNamedElement)
9268 SelectTextString =
"##**" + TextPtr->TextString;
9272 SelectTextString = TextPtr->TextString;
9274 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9283 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9286 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9287 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9326 int MidHPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidVPosBeforeRotate;
9333 Screen->Cursor = TCursor(-2);
9338 catch(
const Exception &e)
9352 Screen->Cursor = TCursor(-11);
9369 int button = Application->MessageBox
9370 (L
"Original selection adjusted to make it square. 'OK' to keep this selection or 'Cancel' to make a new selection",
9371 L
"Left click and hold here to move this message box", MB_OKCANCEL);
9372 if(button == IDCANCEL)
9380 Screen->Cursor = TCursor(-2);
9417 if(IATVecPair.second != IATVecPair.first)
9435 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos < HighSelectVPos))
9442 bool SelectVectorNamedElement =
false;
9443 AnsiString SelectTextString;
9448 SelectVectorNamedElement =
true;
9452 if(SelectVectorNamedElement)
9454 SelectTextString =
"##**" + TextPtr->TextString;
9458 SelectTextString = TextPtr->TextString;
9460 TTextItem TextItem(TextPtr->HPos, TextPtr->VPos, SelectTextString, TextPtr->Font);
9469 for(TTrack::TUserGraphicVector::iterator UserGraphicPtr =
Track->
UserGraphicVector.begin(); UserGraphicPtr < Track->UserGraphicVector.end();
9472 if((UserGraphicPtr->HPos >= LowSelectHPos) && ((UserGraphicPtr->HPos + UserGraphicPtr->Width) < HighSelectHPos) && (UserGraphicPtr->VPos >=
9473 LowSelectVPos) && ((UserGraphicPtr->VPos + UserGraphicPtr->Height) < HighSelectVPos))
9513 int MidVPosAfterRotate = ((
SelectRect.bottom * 16) - 1) + (
SelectRect.left * 16) - MidHPosBeforeRotate;
9519 Screen->Cursor = TCursor(-2);
9524 catch(
const Exception &e)
9544 catch(
const Exception &e)
9563 catch(
const Exception &e)
9581 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Set values or leave blank for no change";
9584 ShowMessage(
"Note: length value will apply to each element's track within the selection.\n\nThis message will not be shown again.");
9594 catch(
const Exception &e)
9612 bool FoundFlag =
false;
9656 catch(
const Exception &e)
9686 catch(
const Exception &e)
9718 bool CheckLocationsExistInRailwayTrue =
true;
9722 Screen->Cursor = TCursor(-11);
9723 std::ifstream TTBLFile(AnsiString(
TimetableDialog->FileName).c_str(), std::ios_base::binary);
9724 if(TTBLFile.is_open())
9726 bool SessionFileFalse =
false;
9734 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
9736 Screen->Cursor = TCursor(-2);
9739 ShowMessage(
"Timetable preliminary integrity check failed - unable to load");
9744 catch(
const Exception &e)
9769 AnsiString LocName =
"";
9774 if((LocName ==
"") && (Train.
MidElement > -1))
9794 if((NextElementPosition > -1) && (NextEntryPos > -1))
9809 if((LocName ==
"") && (Train.
MidElement > -1))
9816 catch(
const Exception &e)
9840 AnsiString LocName =
"";
9845 if((LocName ==
"") && (Train.
MidElement > -1))
9853 if((LocName ==
"") && (Train.
MidElement > -1))
9883 int NextElementPos = -1;
9884 int NextEntryPos = -1;
9900 if((NextElementPos > -1) && (NextEntryPos > -1))
9934 catch(
const Exception &e)
9952 AnsiString LocName =
"";
9957 if((LocName ==
"") && (Train.
MidElement > -1))
9965 if((LocName ==
"") && (Train.
MidElement > -1))
9972 catch(
const Exception &e)
10001 int NextElementPos = -1;
10002 int NextEntryPos = -1;
10008 if((NextElementPos > -1) && (NextEntryPos > -1))
10028 catch(
const Exception &e)
10041 TTrain *TrainToBeJoinedBy;
10054 ShowMessage(
"Can't join two trains when both are without power");
10058 AnsiString TrainToBeJoinedByHeadCode = TrainToBeJoinedBy->
HeadCode;
10060 double OtherBrakeForce = TrainToBeJoinedBy->
MaxBrakeRate * TrainToBeJoinedBy->
Mass;
10062 double CombinedBrakeRate = (OtherBrakeForce + OwnBrakeForce) / (TrainToBeJoinedBy->
Mass + ThisTrain.
Mass);
10063 ThisTrain.
Mass += TrainToBeJoinedBy->
Mass;
10070 AnsiString LocName =
"";
10075 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10079 if((LocName ==
"") && ThisTrain.
LeadElement > -1)
10083 if((LocName ==
"") && (ThisTrain.
MidElement > -1))
10117 catch(
const Exception &e)
10147 AnsiString LocName =
"";
10152 if((LocName ==
"") && (Train.
MidElement > -1))
10160 if((LocName ==
"") && (Train.
MidElement > -1))
10176 catch(
const Exception &e)
10207 catch(
const Exception &e)
10223 if(NextElementPos < 0)
10225 throw Exception(
"Error, no element in front in PassRedSignalMenuItemClick");
10236 throw Exception(
"Error, next element not a signal type in PassRedSignalMenuItemClick");
10250 catch(
const Exception &e)
10276 int NextElementPos = -1;
10278 int NextEntryPos = -1;
10284 if((NextElementPos > -1) && (NextEntryPos > -1))
10293 catch(
const Exception &e)
10312 UnicodeString Message = UnicodeString(Train.
HeadCode) +
" will be removed from the railway - proceed?";
10313 int button = Application->MessageBox(Message.c_str(), L
"Please confirm", MB_YESNO);
10326 AnsiString LocName =
"";
10331 if((LocName ==
"") && (Train.
MidElement > -1))
10339 if((LocName ==
"") && (Train.
MidElement > -1))
10386 int FirstRouteElementVecPos = LeadTrackElement.
Conn[Train.
LeadExitPos];
10472 catch(
const Exception &e)
10487 Application->Terminate();
10501 catch(
const Exception &e)
10515 UnicodeString MessageStr =
10516 "Note that leaving the track unlinked will cause preferred directions to be lost on reloading. Prevent by linking the track then resaving. Do you still wish to exit?";
10517 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10527 UnicodeString MessStr =
"";
10530 MessStr = UnicodeString(
"The railway and the timetable have both changed, exit without saving either?");
10534 MessStr = UnicodeString(
"The railway has changed, exit without saving?");
10538 MessStr = UnicodeString(
"The timetable has changed, exit without saving?");
10540 int button = Application->MessageBox(MessStr.c_str(), L
"Please confirm", MB_YESNO);
10553 UnicodeString MessageStr =
"Please note that the session will be lost if it hasn't been saved. Do you still wish to exit?";
10556 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
10575 catch(
const Exception &e)
10589 if((Shift.Contains(ssAlt)) && (Shift.Contains(ssCtrl)))
10602 else if(Key ==
'3')
10614 else if(Key ==
'4')
10618 else if(Key ==
'5')
10620 TMsgDlgButtons Buttons;
10621 Buttons << mbYes << mbNo;
10622 if(MessageDlg(
"Do you wish to allow facing signals next to bridges? If so please be aware that routes cannot be truncated to these signals.", mtWarning, Buttons, 0) == mrYes)
10632 else if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10636 else if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10649 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
10666 else if(Key == VK_DOWN)
10671 else if(Key == VK_LEFT)
10676 else if(Key == VK_RIGHT)
10681 else if(Key == VK_HOME)
10687 else if(Key == VK_END)
10692 else if(Key == VK_END)
10706 if(Shift.Contains(ssShift) && !Shift.Contains(ssAlt) && !Shift.Contains(ssCtrl) &&
NewHomeButton->Enabled &&
NewHomeButton->Visible)
10717 if(!Shift.Contains(ssCtrl))
10776 if(Key ==
'S' || Key ==
's')
10787 if(Shift.Contains(ssShift))
10803 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl) && !Shift.Contains(ssAlt))
10850 if(Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10855 if(Key ==
'S' || Key ==
's')
10861 if(!Shift.Contains(ssCtrl) && !Shift.Contains(ssShift) && !Shift.Contains(ssAlt))
10873 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10880 if(!Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
10885 if(Key ==
'S' || Key ==
's')
10891 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10912 if(!Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10919 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
10925 if(Key ==
'S' || Key ==
's')
10930 else if(Key ==
'H' || Key ==
'h')
10944 if(Shift.Contains(ssShift) && !Shift.Contains(ssCtrl))
11014 if(
SaveTTButton->Enabled && (Key ==
'T' || Key ==
't'))
11039 if(
FloatingInfoMenu->Enabled && !Shift.Contains(ssAlt) && Shift.Contains(ssCtrl) && Shift.Contains(ssShift))
11041 if(Key ==
'I' || Key ==
'i')
11047 if(Key ==
'S' || Key ==
's')
11051 else if(Key ==
'T' || Key ==
't')
11061 catch(
const Exception &e)
11071 if((Key != VK_SHIFT) && (Key != VK_CONTROL))
11191 catch(
const Exception &e)
11204 Application->HelpKeyword(u
"Introduction");
11206 catch(
const Exception &e)
11216 const UnicodeString Link =
"http://www.railwayoperationsimulator.com";
11217 ::ShellExecute(Handle, NULL, (Link).c_str(), NULL, NULL, SW_SHOWNORMAL);
11240 catch(
const Exception &e)
11266 catch(
const Exception &e)
11292 catch(
const Exception &e)
11348 bool ErrorFlag =
false, TooBigFlag =
false;
11369 if(!ErrorFlag && !TooBigFlag)
11379 int KPH = (MPH * 1.609344) + 0.5;
11386 int MPH = (KPH * 0.621371) + 0.5;
11397 catch(
const EConvertError &ec)
11401 catch(
const Exception &e)
11436 bool ErrorFlag =
false, TooBigFlag =
false;
11457 if(!ErrorFlag && !TooBigFlag)
11467 int KW = (HP * 0.745699872) + 0.5;
11474 int HP = (KW * 1.340482574) + 0.5;
11485 catch(
const EConvertError &ec)
11489 catch(
const Exception &e)
11502 bool ErrorFlag =
false, TooBigFlag =
false;
11523 if(!ErrorFlag && !TooBigFlag)
11533 int KPH = (MPH * 1.609344) + 0.5;
11540 int MPH = (KPH * 0.621371) + 0.5;
11551 catch(
const EConvertError &ec)
11555 catch(
const Exception &e)
11569 bool ErrorFlag =
false, TooLongFlag =
false;
11572 for(
int x = 1; x <=
MileEdit->Text.Length(); x++)
11584 for(
int x = 1; x <=
ChainEdit->Text.Length(); x++)
11596 for(
int x = 1; x <=
YardEdit->Text.Length(); x++)
11608 TooLongFlag =
true;
11611 if(!ErrorFlag && !TooLongFlag)
11613 int Miles = 0, Chains = 0, Yards = 0, Metres = 0;
11626 Metres = int((Miles * 1609.344) + (Chains * 20.1168) + (Yards * 0.9144) + 0.5);
11635 catch(
const EConvertError &ec)
11639 catch(
const Exception &e)
11670 catch(
const Exception &e)
11706 "Changes have been made to the timetable clock - you may wish to save a session before resuming operation.\n\nTo cancel all changes re-click the 'Adjust the timetable clock' button then click the reset button BEFORE resuming operation.";
11713 catch(
const Exception &e)
11731 catch(
const Exception &e)
11750 catch(
const Exception &e)
11769 catch(
const Exception &e)
11788 catch(
const Exception &e)
11807 catch(
const Exception &e)
11826 catch(
const Exception &e)
11845 catch(
const Exception &e)
11864 catch(
const Exception &e)
11882 catch(
const Exception &e)
11896 double TTClockIncrement = 1.0 / 24;
11902 catch(
const Exception &e)
11916 double TTClockIncrement = 1.0 / 144;
11922 catch(
const Exception &e)
11936 double TTClockIncrement = 1.0 / 1440;
11942 catch(
const Exception &e)
11983 catch(
const Exception &e)
11997 InfoPanel->Caption =
"PRE-START: Presetting automatic signal routes";
12008 Screen->Cursor = TCursor(-11);
12010 bool PointsChanged, AtLeastOneSet =
false;
12011 int LastIteratorValue = 0;
12018 AtLeastOneSet =
true;
12034 ShowMessage(
"No presettable automatic signal routes are available");
12036 Screen->Cursor = TCursor(-2);
12039 catch(
const Exception &e)
12053 int DispW = (
Interface->Width - 64 - 16) / 16;
12055 int DispH = (
Interface->Height - 192) / 16;
12087 catch(
const Exception &e)
12117 catch(
const Exception &e)
12143 SigImagePanel->Caption =
"Signals will be on the right hand side of the track";
12148 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12151 ShowMessage(
"Failed to store right hand signal setting, program will default to left hand signals when next loaded");
12169 SigImagePanel->Caption =
"Signals will be on the left hand side of the track";
12174 std::ofstream SigFile((
CurDir +
"\\Signal.hnd").c_str());
12186 catch(
const Exception &e)
12205 bool TooBigFlag =
false, BadCharsFlag =
false;
12210 for(
int x = 1; x <=
MTBFEditBox->Text.Length(); x++)
12214 BadCharsFlag =
true;
12227 ShowMessage(
"Maximum value allowed is 10,000");
12236 ShowMessage(
"Value must be a whole number with no special characters");
12253 catch(
const Exception &e)
12271 "Values can only be entered or changed in Pre-Start mode\ni.e. after selecting 'Operate railway' but before clicking 'Run'");
12275 catch(
const Exception &e)
12307 catch(
const Exception &e)
12333 catch(
const Exception &e)
12349 catch(
const Exception &e)
12370 catch(
const Exception &e)
12387 catch(
const Exception &e)
12404 catch(
const Exception &e)
12420 ShowMessage(
"No boxes ticked!");
12424 Screen->Cursor = TCursor(-11);
12425 AnsiString TTTitle;
12439 ShowMessage(
"Analysis complete and file created");
12444 Screen->Cursor = TCursor(-2);
12447 catch(
const Exception &e)
12489 int WidthNum = int(
MainScreen->Width / 160) + 1;
12490 int HeightNum = int(
MainScreen->Height / 144) + 1;
12491 for(
int x = 0; x < WidthNum; x++)
12493 for(
int y = 0; y < HeightNum; y++)
12606 bool BreakFlag =
false;
12708 ZoomButton->Glyph->LoadFromResourceName(0,
"ZoomOut");
12734 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting element";
12750 UnicodeString MessageStr =
"The railway has changed, close it without saving?";
12751 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
12798 std::ifstream VecFile(FileName);
12800 if(VecFile.is_open())
12820 bool GraphicsFollow =
false;
12821 int NumberOfActiveElements;
12834 if(!(EveryPrefDir->CheckOnePrefDir(0, NumberOfActiveElements, VecFile)))
12865 TDateTime First, Second;
12866 bool Finished =
false;
12868 First = TDateTime::CurrentDateTime();
12869 double TimeVal1 = 86400000 * double(First);
12873 Second = TDateTime::CurrentDateTime();
12874 double TimeVal2 = 86400000 * double(Second);
12875 if((TimeVal2 - TimeVal1) > Msec)
12925 if((LinkNumber1 == 1) || (LinkNumber1 == 3) || (LinkNumber1 == 7) || (LinkNumber1 == 9))
12933 if((LinkNumber2 == 1) || (LinkNumber2 == 3) || (LinkNumber2 == 7) || (LinkNumber2 == 9))
13085 InfoPanel->Caption =
"Select an option from the File, Mode or Help menus";
13241 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select preferred direction start location (right click to erase)";
13303 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13317 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13344 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
13345 " in the folder where the 'Railway.exe' program file resides");
13386 OAListBox->Items->Add(L
"to locate train");
13391 OAListBox->Items->Add(L
"Left click and");
13392 OAListBox->Items->Add(L
"hold grey area");
13393 OAListBox->Items->Add(L
"to move panel");
13423 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
13446 OAListBox->Items->Add(L
"to locate train");
13451 OAListBox->Items->Add(L
"Left click and");
13452 OAListBox->Items->Add(L
"hold grey area");
13453 OAListBox->Items->Add(L
"to move panel");
13467 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13476 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
13513 InfoPanel->Caption =
"ADDING TRACK: Select element then left click to add it. Right click an element to remove it.";
13534 InfoPanel->Caption =
"ADDING GRAPHIC: Left click layout to add SELECTED graphic, right click to remove ANY graphic.";
13539 InfoPanel->Caption =
"SELECTING USER GRAPHIC: Select the graphic file then add as many as necessary to the layout.";
13543 int HLoc, VLoc, Count;
13545 if(div(Count, 2).rem == 1)
13547 ShowMessage(
"Can't connect, there are an odd number of gaps");
13562 ShowMessage(
"Error - Even number of gaps but all set after first call to HighLightOneGap");
13572 InfoPanel->Caption =
"CONNECTING GAPS: Click on connecting gap";
13579 InfoPanel->Caption =
"ADDING/EDITING TEXT: Left click to add, right click first letter to erase, or left click first letter to edit)";
13594 InfoPanel->Caption =
"MOVING TEXT OR GRAPHIC: If text left click first letter, if graphic left click anywhere, then drag";
13601 InfoPanel->Caption =
"NAMING LOCATIONS: Click on location element to add or change name";
13609 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select first location (only non-default elements marked)";
13620 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Select next location";
13622 InfoPanel->Caption =
"DISTANCE/SPEED SETTING: Continue or set values (overall length), or right click to cancel/truncate";
13634 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
13644 InfoPanel->Caption =
"COPYING: Left click in selection && drag";
13668 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false; ;
13669 int ErasedTrackVectorPosition;
13670 Screen->Cursor = TCursor(-11);
13672 InfoPanel->Caption =
"CUT PROCESSING: Please do not click the mouse";
13679 if(EraseSuccessfulFlag)
13681 if(ErasedTrackVectorPosition > -1)
13691 int HighSelectVPos =
SelectRect.bottom * 16;
13697 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13703 TextChangesMade =
true;
13713 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13714 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13717 GraphicChangesMade =
true;
13724 Screen->Cursor = TCursor(-2);
13729 InfoPanel->Caption =
"CUTTING: Left click in selection && drag";
13745 if(NeedToLink || TextChangesMade || GraphicChangesMade)
13760 bool NeedToLink =
false;
13761 bool TrackLinkingRequiredFlag;
13762 Screen->Cursor = TCursor(-11);
13764 InfoPanel->Caption =
"PASTING: Please wait";
13771 bool TrackEraseSuccessfulFlag;
13772 int ErasedTrackVectorPosition;
13774 for(
int x = LowSelectHLoc; x < HighSelectHLoc; x++)
13776 for(
int y = LowSelectVLoc; y < HighSelectVLoc; y++)
13779 if(ErasedTrackVectorPosition > -1)
13794 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13809 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13810 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13831 bool InternalChecks =
false;
13835 TrackLinkingRequiredFlag, InternalChecks);
13851 if(TrackLinkingRequiredFlag)
13859 TextPtr->HPos += HDiff * 16;
13860 TextPtr->VPos += VDiff * 16;
13861 AnsiString TempString = TextPtr->TextString;
13877 if(TextPtr->TextString.SubString(1, 4) ==
"##**")
13879 TempString = TextPtr->TextString.SubString(5, TextPtr->TextString.Length());
13882 TextPtr->TextString =
"";
13894 for(TTrack::TUserGraphicVector::iterator GraphicPtr =
Track->
SelectGraphicVector.begin(); GraphicPtr < Track->SelectGraphicVector.end();
13897 GraphicPtr->HPos += HDiff * 16;
13898 GraphicPtr->VPos += VDiff * 16;
13911 Screen->Cursor = TCursor(-2);
13925 UnicodeString MessageStr =
"Selected area will be deleted - proceed?";
13926 int button = Application->MessageBox(MessageStr.c_str(), L
"Please confirm", MB_YESNO);
13931 bool EraseSuccessfulFlag, NeedToLink =
false, TextChangesMade =
false, GraphicChangesMade =
false;
13932 int ErasedTrackVectorPosition;
13933 Screen->Cursor = TCursor(-11);
13935 InfoPanel->Caption =
"DELETING: Please wait";
13942 if(EraseSuccessfulFlag)
13944 if(ErasedTrackVectorPosition > -1)
13954 int HighSelectVPos =
SelectRect.bottom * 16;
13960 AnsiString Check = TextPtr->TextString;
13961 if((TextPtr->HPos >= LowSelectHPos) && (TextPtr->HPos < HighSelectHPos) && (TextPtr->VPos >= LowSelectVPos) && (TextPtr->VPos <
13967 TextChangesMade =
true;
13986 if((GraphicPtr->HPos >= LowSelectHPos) && ((GraphicPtr->HPos + GraphicPtr->Width) < HighSelectHPos) && (GraphicPtr->VPos >= LowSelectVPos)
13987 && ((GraphicPtr->VPos + GraphicPtr->Height) < HighSelectVPos))
13992 if((UserGraphicPtr->HPos == GraphicPtr->HPos) && (UserGraphicPtr->VPos == GraphicPtr->VPos) &&
13993 (UserGraphicPtr->Width == GraphicPtr->Width) && (UserGraphicPtr->Height == GraphicPtr->Height) &&
13994 (UserGraphicPtr->FileName == GraphicPtr->FileName))
13997 GraphicChangesMade =
true;
14014 if(NeedToLink || TextChangesMade || GraphicChangesMade)
14018 Screen->Cursor = TCursor(-2);
14070 bool LeadingPointsAtLastElement =
false;
14073 if(LeadingPointsAtLastElement)
14075 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Can't end on leading points, select next location or truncate";
14080 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Select next preferred direction location (right click to truncate)";
14085 InfoPanel->Caption =
"PREFERRED DIRECTION SETTING: Add selection or select next location (right click to truncate)";
14100 InfoPanel->Caption =
"SELECTING: Select area - click left mouse && drag";
14140 OperateButton->Glyph->LoadFromResourceName(0,
"PauseGraphic");
14183 Display->
PerformanceLog(15, TimeMessage +
"Timetable clock speed changed to one sixteenth normal");
14188 if(TTClockTimeChange > 0.000347)
14191 int MinsIncrease = ((TTClockTimeChange * 1440) + 0.5);
14192 int HoursIncrease = 0;
14193 while(MinsIncrease >= 60)
14196 MinsIncrease -= 60;
14198 if(HoursIncrease == 0)
14199 TimeMessage +=
"Timetable clock incremented by " + AnsiString(MinsIncrease) +
"m";
14200 else if(MinsIncrease == 0)
14201 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h";
14203 TimeMessage +=
"Timetable clock incremented by " + AnsiString(HoursIncrease) +
"h " + AnsiString(MinsIncrease) +
"m";
14214 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14222 MTBFLabel->Caption =
"Mean time between\ntrain failures in\ntimetable hours";
14231 OperateButton->Glyph->LoadFromResourceName(0,
"RunGraphic");
14259 float LockDelay = 120.0;
14265 bool BreakFlag =
false;
14269 if((TTClockTime - LRVIT->LockStartTime) > TDateTime(LockDelay / 86400))
14272 AnsiString(LRVIT->LastTrackVectorPosition));
14273 while(Route.
LastElementPtr(9)->GetTrackVectorPosition() != LRVIT->TruncateTrackVectorPosition)
14286 if(Route.
LastElementPtr(17)->GetTrackVectorPosition() == LRVIT->TruncateTrackVectorPosition)
14325 int TempLockedVectorNumber;
14335 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->FirstDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 0))
14338 AutoSigVectorIT->AccessNumber++;
14341 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->SecondDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 1))
14344 AutoSigVectorIT->AccessNumber++;
14347 if(((TTClockTime - AutoSigVectorIT->PassoutTime) > TDateTime(AutoSigVectorIT->ThirdDelay / 86400)) && (AutoSigVectorIT->AccessNumber == 2))
14350 AutoSigVectorIT->AccessNumber++;
14358 if(AutoSigVectorIT->AccessNumber > 2)
14373 TPoint MousePoint = Mouse->CursorPos;
14374 int ScreenX = MousePoint.x -
MainScreen->ClientOrigin.x;
14375 int ScreenY = MousePoint.y -
MainScreen->ClientOrigin.y;
14377 if((ScreenX > (
MainScreen->Width - 1)) || (ScreenY > (
MainScreen->Height - 1)) || (ScreenX < 0) || (ScreenY < 0))
14387 ((MousePoint.y - ClientOrigin.y) >=
PerformancePanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14399 ((MousePoint.y - ClientOrigin.y) >=
OperatorActionPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14411 ((MousePoint.y - ClientOrigin.y) >=
TimetableEditPanel->Top) && ((MousePoint.y - ClientOrigin.y) <=
14420 AnsiString TrackFloat =
"", TrainStatusFloat =
"", TrainTTFloat =
"";
14422 bool ShowTrackFloatFlag =
false, ShowTrainStatusFloatFlag =
false, ShowTrainTTFloatFlag =
false;
14434 bool ActiveTrackFoundFlag =
false, InactiveTrackFoundFlag =
false, TwoTrack =
false;
14435 AnsiString Length01Str =
"", Length23Str =
"", SpeedLimit01Str =
"", SpeedLimit23Str =
"";
14436 AnsiString StationEntryStopLinkPos1Str =
"", StationEntryStopLinkPos2Str =
"";
14437 AnsiString ATrackSN =
"", ATrackTN =
"", IATrackSN =
"", LengthAndSpeedCaption =
"";
14438 AnsiString SigAspectString =
"";
14442 if(InactiveTrackFoundFlag)
14447 if(ActiveTrackFoundFlag)
14454 if((ATrackTN !=
"") && (!InactiveTrackFoundFlag || ((InactiveTrackElement.
TrackType !=
Platform) &&
14458 ShowMessage(
"Error - Track has timetable name without corresponding plat/named loc");
14463 ShowMessage(
"Error - plat/named loc and track have different names, or plat/named loc named but not track");
14469 Length01Str = AnsiString(ActiveTrackElement.
Length01);
14470 if(Length01Str ==
"-1")
14471 Length01Str =
"Not Set";
14472 SpeedLimit01Str = AnsiString(ActiveTrackElement.
SpeedLimit01);
14473 if(SpeedLimit01Str ==
"-1")
14474 SpeedLimit01Str =
"Not Set";
14477 Length23Str = AnsiString(ActiveTrackElement.
Length23);
14478 if(Length23Str ==
"-1")
14479 Length23Str =
"Not Set";
14480 SpeedLimit23Str = AnsiString(ActiveTrackElement.
SpeedLimit23);
14481 if(SpeedLimit23Str ==
"-1")
14482 SpeedLimit23Str =
"Not Set";
14485 LengthAndSpeedCaption =
"Straight track length = " + Length01Str +
" m" +
'\n' +
"Diverging track length = " + Length23Str +
" m" +
'\n' +
14486 "Straight track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Diverging track speed limit = " + SpeedLimit23Str +
" km/h";
14490 LengthAndSpeedCaption =
"Left diverging track length = " + Length01Str +
" m" +
'\n' +
"Right diverging track length = " + Length23Str +
14491 " m" +
'\n' +
"Left diverging track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Right diverging track Speed Limit = " +
14492 SpeedLimit23Str +
" km/h";
14497 if((ActiveTrackElement.
SpeedTag == 15) || (ActiveTrackElement.
SpeedTag == 46))
14499 LengthAndSpeedCaption =
"Horizontal track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14500 "Horizontal track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14502 else if(ActiveTrackElement.
SpeedTag == 47)
14504 LengthAndSpeedCaption =
"Horizontal track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14505 "Horizontal track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14507 else if(ActiveTrackElement.
SpeedTag == 45)
14509 LengthAndSpeedCaption =
"Vertical track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
" m" +
'\n' +
14510 "Vertical track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit23Str +
" km/h";
14512 else if(ActiveTrackElement.
SpeedTag == 44)
14514 LengthAndSpeedCaption =
"Vertical track length = " + Length23Str +
" m" +
'\n' +
"Other track length = " + Length01Str +
" m" +
'\n' +
14515 "Vertical track speed limit = " + SpeedLimit23Str +
" km/h" +
'\n' +
"Other track speed limit = " + SpeedLimit01Str +
" km/h";
14517 else if(ActiveTrackElement.
SpeedTag == 16)
14519 LengthAndSpeedCaption =
"Top left to bottom right track length = " + Length01Str +
" m" +
'\n' +
"Other track length = " + Length23Str +
14520 " m" +
'\n' +
"Top left to bottom right track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Other track speed limit = " +
14521 SpeedLimit23Str +
" km/h";
14526 LengthAndSpeedCaption =
"Top track length = " + Length01Str +
" m" +
'\n' +
"Bottom track length = " + Length23Str +
" m" +
'\n' +
14527 "Top track speed limit = " + SpeedLimit01Str +
" km/h" +
'\n' +
"Bottom track speed limit = " + SpeedLimit23Str +
" km/h";
14532 LengthAndSpeedCaption =
"Track length = " + Length01Str +
" m" +
'\n' +
"Track speed limit = " + SpeedLimit01Str +
" km/h";
14535 if(ActiveTrackFoundFlag)
14539 ShowTrackFloatFlag =
true;
14542 TrackFloat =
"Location = " + ATrackTN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14544 else if(ATrackSN !=
"")
14546 TrackFloat =
"Location = " + ATrackSN +
'\n' + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14549 else if(InactiveTrackFoundFlag)
14551 TrackFloat =
"Location unnamed\n" + LengthAndSpeedCaption +
'\n' +
"ID = " + AnsiString(ActiveTrackElement.
ElementID);
14556 TrackFloat = LengthAndSpeedCaption +
'\n' +
"Track Element ID = " + AnsiString(ActiveTrackElement.
ElementID);
14562 SigAspectString =
"\nThree-aspect signal";
14566 SigAspectString =
"\nTwo-aspect signal";
14570 SigAspectString =
"\nGround signal";
14574 SigAspectString =
"\nFour-aspect signal";
14576 TrackFloat += SigAspectString;
14579 else if(InactiveTrackFoundFlag)
14582 ShowTrackFloatFlag =
true;
14585 if(IATrackSN ==
"")
14587 TrackFloat =
"Location unnamed\nID = " + AnsiString(InactiveTrackElement.
ElementID);
14591 TrackFloat =
"Location = " + IATrackSN +
'\n' +
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14596 TrackFloat =
"ID = " + AnsiString(InactiveTrackElement.
ElementID);
14606 AnsiString FormatOneDPStr =
"####0.0";
14607 AnsiString FormatNoDPStr =
"#######0";
14609 AnsiString MaxBrakeStr =
"";
14610 AnsiString SpecialStr =
"", MaxSpeedStr =
"";
14620 ShowTrainStatusFloatFlag =
true;
14621 AnsiString HeadCode =
"", ServiceReferenceInfo =
"", Status =
"", CurrSpeedStr =
"", BrakePCStr =
"", NextStopStr =
"", TimeLeftStr =
"",
14622 TimeToNextMovementStr =
"", MassStr =
"", PowerStr =
"";
14624 MassStr = AnsiString::FormatFloat(FormatNoDPStr, ((
double)Train.
Mass) / 1000);
14625 PowerStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
PowerAtRail / 1000 / 0.8);
14627 MaxSpeedStr =
"30";
14629 MaxSpeedStr = AnsiString::FormatFloat(FormatNoDPStr, Train.
MaxRunningSpeed);
14633 TDateTime TimeLeft;
14635 MaxBrakeStr = AnsiString::FormatFloat(FormatNoDPStr, (Train.
MaxBrakeRate * Train.
Mass / 9810));
14644 ServiceReferenceInfo =
"\nFirst service";
14647 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber);
14649 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(Train.
RepeatNumber) +
" of ref. " +
14660 Status =
"Stopped on signaller's instruction";
14662 Status =
"Not in service";
14664 Status =
"Stopped at buffers";
14666 Status =
"Stopped at signal";
14668 Status =
"Stopped - forward track occupied";
14676 Status =
"Stopped without power - train failed";
14678 Status =
"Stopped without power";
14681 Status =
"Stopped - signal passed at danger";
14683 Status =
"Derailed";
14685 Status =
"Crashed";
14692 Status =
"Accelerating";
14699 if(BrakePCRate < 55)
14700 Status =
"Light braking";
14701 else if(BrakePCRate < 90)
14702 Status =
"Heavy braking";
14704 Status =
"Emergency braking";
14710 if(BrakePCRate < 55)
14711 Status =
"Light braking";
14712 else if(BrakePCRate < 90)
14713 Status =
"Heavy braking";
14715 Status =
"Emergency braking";
14721 Status =
"Accelerating";
14727 Status =
"Accelerating";
14729 ((Train.
ExitSpeedFull - Train.
ExitSpeedHalf) * (
double(ElapsedDeltaT - FirstHalfTimeDeltaT) / double(SecondHalfTimeDeltaT)));
14738 Status =
"Coasting - train failed";
14742 Status =
"Coasting - no power";
14748 Status =
"Constant speed";
14759 Status =
"Coasting - train failed";
14763 Status =
"Coasting - no power";
14769 Status =
"Constant speed";
14776 NextStopStr =
"At signaller's discretion";
14778 NextStopStr =
"None";
14784 SpecialStr =
"Train under signaller control" + AnsiString(
'\n');
14788 SpecialStr =
"Restricted speed - being called on" + AnsiString(
'\n');
14792 if(RemTimeHalf < 0)
14795 if(RemTimeFull < 0)
14797 if(RemTimeHalf > 0)
14798 TimeLeft = RemTimeHalf;
14800 TimeLeft = RemTimeFull;
14801 TimeToNextMovementStr =
"Time to next movement (sec) = " + TimeLeftStr.FormatFloat(FormatOneDPStr, TimeLeft);
14803 TimeToNextMovementStr =
"";
14807 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14808 Status +
'\n' +
"Next: " + NextStopStr;
14813 MaxSpeedStr +
"km/h; Power " + PowerStr +
"kW" +
'\n' +
"Mass " + MassStr +
"Te; Brakes " + MaxBrakeStr +
"Te" +
'\n' + SpecialStr +
14814 Status +
": " + CurrSpeedStr.FormatFloat(FormatNoDPStr, CurrSpeed) +
"km/h" +
'\n' +
"Next: " + NextStopStr;
14819 ShowTrainTTFloatFlag =
true;
14828 TrainStatusFloat =
"No trains expected";
14829 TrainTTFloat =
"No timetable";
14833 ShowTrainStatusFloatFlag =
true;
14835 ShowTrainTTFloatFlag =
true;
14842 (CTEIt->second.TrainDataEntryPtr->TrainOperatingDataVector.at(CTEIt->second.RepeatNumber).RunningEntry !=
NotStarted)))
14849 AnsiString ServiceReferenceInfo =
"";
14853 if(CTEIt->second.RepeatNumber == 0)
14856 ServiceReferenceInfo =
"\nFirst service of ref. " + TTDEPtr->
ServiceReference;
14858 ServiceReferenceInfo =
"\nFirst service";
14861 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber);
14863 ServiceReferenceInfo =
"\nRepeat service no. " + AnsiString(CTEIt->second.RepeatNumber) +
" of ref. " +
14869 ServiceReferenceInfo =
"\nService reference " + TTDEPtr->
ServiceReference;
14873 SpecialStr =
"\nTrain under signaller control";
14875 if(EntrySpeed > LineSpeedLimit)
14876 EntrySpeed = LineSpeedLimit;
14881 if(EntrySpeed > LineSpeedLimit)
14882 EntrySpeed = LineSpeedLimit;
14886 TDateTime TempTime = CTEIt->first;
14888 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14889 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nDelayed, was due at " +
14894 TDateTime TempTime = CTEIt->first;
14896 TrainStatusFloat = CTEIt->second.HeadCode +
": " + CTEIt->second.Description + ServiceReferenceInfo +
"\nEntry speed " +
14897 AnsiString::FormatFloat(FormatNoDPStr, EntrySpeed) +
"km/h" + SpecialStr +
"\nExpected at " +
14905 CTEIt->second.IncrementalMinutes, CTEIt->second.IncrementalDigits);
14916 AnsiString Caption;
14918 if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14924 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14926 Caption = TrackFloat;
14928 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14930 Caption = TrainStatusFloat;
14932 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && !ShowTrainTTFloatFlag)
14934 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14936 else if(!ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14938 if(TrainStatusFloat ==
"No trains expected")
14939 Caption = TrainStatusFloat;
14941 Caption = TrainTTFloat;
14943 else if(ShowTrackFloatFlag && !ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14945 if(TrainStatusFloat ==
"No trains expected")
14946 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14948 Caption = TrainTTFloat +
'\n' +
'\n' + TrackFloat;
14950 else if(!ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14952 if(TrainStatusFloat ==
"No trains expected")
14953 Caption = TrainStatusFloat;
14955 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat;
14957 else if(ShowTrackFloatFlag && ShowTrainStatusFloatFlag && ShowTrainTTFloatFlag)
14959 if(TrainStatusFloat ==
"No trains expected")
14960 Caption = TrainStatusFloat +
'\n' +
'\n' + TrackFloat;
14962 Caption = TrainStatusFloat +
'\n' +
'\n' + TrainTTFloat +
'\n' +
'\n' + TrackFloat;
15079 InfoPanel->Caption =
"PRE-START: Route setting in progress";
15081 InfoPanel->Caption =
"OPERATING: Route setting in progress";
15203 bool Manual =
false;
15250 throw Exception(
"Failed to find a route at LC position HLoc = " + (AnsiString)H +
" VLoc = " + (AnsiString)V);
15255 if(RouteNumber > -1)
15289 bool SaveRailwayButtonsFlag =
true;
15298 SaveRailwayButtonsFlag =
false;
15315 SaveRailwayButtonsFlag =
false;
15323 SaveRailwayButtonsFlag =
false;
15376 bool ZoomFlag =
true, HomeFlag =
true, NewHomeFlag =
true, ScreenLeftFlag =
true, ScreenRightFlag =
true, ScreenUpFlag =
true, ScreenDownFlag =
true,
15377 TrackBuildPanelEnabledFlag =
true, PrefDirPanelEnabledFlag =
true, OperatingPanelEnabledFlag =
true, TimetablePanelEnabledFlag =
true;
15379 AnsiString TrackBuildPanelLabelCaptionStr =
"Build/modify";
15380 AnsiString PrefDirPanelLabelCaptionStr =
"Preferred direction selection";
15381 AnsiString OperatingPanelLabelCaptionStr =
"Operation";
15382 AnsiString TimetablePanelLabelCaptionStr =
"Timetable editor";
15387 ScreenLeftFlag =
false;
15389 ScreenRightFlag =
false;
15391 ScreenUpFlag =
false;
15393 ScreenDownFlag =
false;
15398 ScreenLeftFlag =
false;
15400 ScreenRightFlag =
false;
15402 ScreenUpFlag =
false;
15404 ScreenDownFlag =
false;
15410 NewHomeFlag =
false;
15411 ScreenLeftFlag =
false;
15412 ScreenRightFlag =
false;
15413 ScreenUpFlag =
false;
15414 ScreenDownFlag =
false;
15420 TrackBuildPanelEnabledFlag =
false;
15421 TrackBuildPanelLabelCaptionStr =
"Disabled";
15422 PrefDirPanelEnabledFlag =
false;
15423 PrefDirPanelLabelCaptionStr =
"Disabled";
15424 OperatingPanelEnabledFlag =
false;
15425 OperatingPanelLabelCaptionStr =
"Disabled";
15426 TimetablePanelEnabledFlag =
false;
15427 TimetablePanelLabelCaptionStr =
"Disabled";
15435 OperatingPanelEnabledFlag =
false;
15436 OperatingPanelLabelCaptionStr =
"Disabled";
15439 NewHomeFlag =
false;
15440 ScreenLeftFlag =
false;
15441 ScreenRightFlag =
false;
15442 ScreenUpFlag =
false;
15443 ScreenDownFlag =
false;
15457 NewHomeFlag =
false;
15458 ScreenLeftFlag =
false;
15459 ScreenRightFlag =
false;
15460 ScreenUpFlag =
false;
15461 ScreenDownFlag =
false;
15468 NewHomeFlag =
false;
15469 ScreenLeftFlag =
false;
15470 ScreenRightFlag =
false;
15471 ScreenUpFlag =
false;
15472 ScreenDownFlag =
false;
15480 NewHomeFlag =
false;
15481 ScreenLeftFlag =
false;
15482 ScreenRightFlag =
false;
15483 ScreenUpFlag =
false;
15484 ScreenDownFlag =
false;
15509 if(ScreenRightFlag)
15521 if(OperatingPanelEnabledFlag)
15525 if(TrackBuildPanelEnabledFlag)
15529 if(PrefDirPanelEnabledFlag)
15533 if(TimetablePanelEnabledFlag)
15552 bool CallOnValid =
false;
15558 CallOnValid =
true;
15651 Screen->Cursor = TCursor(-2);
15694 Caption =
"Railway: New railway under development";
15696 Caption =
"Railway: " +
RailwayTitle +
" under development";
15785 TFont *TempFont =
new TFont;
15787 TempFont->Style.Clear();
15788 TempFont->Name =
"MS Sans Serif";
15789 TempFont->Size = 10;
15791 TempFont->Charset = (TFontCharset)(0);
15897 if(NonPrefDirChangesMade)
15921 AnsiString CurrentDateTimeStr =
"", TimetableTimeStr =
"", SessionFileStr =
"";
15922 Screen->Cursor = TCursor(-11);
15923 CurrentDateTimeStr = TDateTime::CurrentDateTime().FormatString(
"dd-mm-yyyy hh.nn.ss");
15926 TimetableTimeStr = TimetableTimeStr.SubString(1, 2) +
'.' + TimetableTimeStr.SubString(4, 2) +
'.' + TimetableTimeStr.SubString(7, 2);
15929 SessionFileStr =
LoadSessionDialog->InitialDir +
"\\Session " + CurrentDateTimeStr +
"; Timetable time " + TimetableTimeStr +
"; " +
RailwayTitle +
15931 std::ofstream SessionFile(SessionFileStr.c_str());
15932 if(!(SessionFile.fail()))
15974 SessionFile.close();
15975 DeleteFile(SessionFileStr);
15976 Screen->Cursor = TCursor(-2);
16008 SessionFile.close();
16018 Screen->Cursor = TCursor(-2);
16021 catch(
const Exception &e)
16054 Screen->Cursor = TCursor(-11);
16059 if(!(SessionFile.fail()))
16066 int LastCharBeforeFloat = TempString.LastDelimiter(
'*');
16067 if((LastCharBeforeFloat == 0) || (LastCharBeforeFloat == TempString.Length()))
16074 AnsiString FloatStr = TempString.SubString(LastCharBeforeFloat + 1, TempString.Length() - LastCharBeforeFloat);
16090 bool GraphicsFollow =
false;
16106 SessionFile.close();
16107 Screen->Cursor = TCursor(-2);
16108 ShowMessage(
"Corruption in preferred direction section of the session file, session can't be loaded");
16116 SessionFile.close();
16117 Screen->Cursor = TCursor(-2);
16118 ShowMessage(
"Corruption in route section of the session file, session can't be loaded");
16130 if(TempString ==
"***BarriersDownVector***")
16138 SessionFile.close();
16139 Screen->Cursor = TCursor(-2);
16140 ShowMessage(
"Unable to load timetable section of the session file, session can't be loaded");
16147 SessionFile.close();
16148 Screen->Cursor = TCursor(-2);
16149 throw Exception(
"TimetableTitle null in LoadSession");
16167 ShowMessage(
"Performance logfile failed to open, logs won't be saved. Ensure that there is a folder named " +
PERFLOG_DIR_NAME +
16168 " in the folder where the 'Railway.exe' program file resides");
16174 SessionFile.get(TempChar);
16175 while(!SessionFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
16177 SessionFile.get(TempChar);
16179 if(SessionFile.eof())
16183 SessionFile.close();
16194 double PowerDouble;
16202 SessionFile.close();
16238 ShowMessage(
"Session file integrity check failed, unable to load session.");
16240 Screen->Cursor = TCursor(-2);
16244 catch(
const Exception &e)
16246 if((e.Message.Pos(
"esource") > 0) || (e.Message.Pos(
"arameter") > 0))
16248 Screen->Cursor = TCursor(-2);
16259 UnicodeString MessageStr =
16260 "Insufficient memory available to load the file, and partial load likely to be corrupt. Application will terminate. Try loading the session as the first action after reloading the program.";
16262 Application->MessageBox(MessageStr.c_str(), L
"Out of memory", MB_OK | MB_ICONERROR);
16263 Application->Terminate();
16334 if(OpMode ==
"PreStart")
16392 AnsiString OpMode =
"";
16399 else if((OpMode !=
"PreStart") && (OpMode !=
"NotPreStart"))
16631 SessionFile.close();
16632 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16646 ShowMessage(
"Failed to open temporary timetable file. Unable to save the session");
16652 char *Buffer =
new char[10000];
16657 BytesRead = FileRead(Handle, Buffer, 10000);
16658 SessionFile.write(Buffer, BytesRead);
16659 if(BytesRead < 10000)
16665 SessionFile.close();
16666 SessionFile.open(SessionFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16690 if(!FileExists(TimetableFileName))
16697 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::binary);
16699 int Handle = FileOpen(TimetableFileName, fmOpenRead);
16706 Handle = FileOpen(TimetableFileName, fmOpenRead);
16716 char *Buffer =
new char[10000];
16721 BytesRead = FileRead(Handle, Buffer, 10000);
16722 ErrorFile.write(Buffer, BytesRead);
16723 if(BytesRead < 10000)
16730 ErrorFile.open(ErrorFileStr.c_str(), std::ios_base::app | std::ios_base::out);
16758 int TempTTFileNumber = 0;
16760 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
16762 TempTTFileNumber++;
16770 if(!TTBFile.fail())
16772 char *Buffer =
new char[10000];
16773 char TempChar = (char)(SessionFile.peek());
16774 if(TempChar ==
'\n')
16775 SessionFile.get(TempChar);
16776 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16785 for(
int x = 0; x < 10000; x++)
16787 if(Buffer[x] !=
'\0')
16792 while(AnsiString(Buffer) !=
"***End***")
16794 TTBFile.write(Buffer, Count);
16795 TTBFile.write(&Zero, 1);
16797 if(!SessionFile.getline(Buffer, 10000,
'\0'))
16806 for(
int x = 0; x < 10000; x++)
16808 if(Buffer[x] !=
'\0')
16818 bool GiveMessagesFalse =
false;
16819 bool CheckLocationsExistInRailwayTrue =
true;
16822 std::ifstream TTBLFile(
TempTTFileName.c_str(), std::ios_base::binary);
16823 if(TTBLFile.is_open())
16825 bool SessionFileTrue =
true;
16856 for(
int x = 0; x < NumberOfTrainEntries; x++)
16864 for(
int y = 0; y < NumberOfTrains; y++)
16889 AnsiString OutString;
16896 while(OutString !=
"***End***")
16905 if(SessionFile.fail())
16910 int NumberOfTrainEntries;
16917 for(
int x = 0; x < NumberOfTrainEntries; x++)
16919 int NumberOfTrains;
16925 for(
int y = 0; y < NumberOfTrains; y++)
16954 bool EndOfFile =
false;
16956 char *TrainTimetableString =
new char[10000];
16960 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16961 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16967 AnsiString OneLine(TrainTimetableString);
16968 bool FinalCallTrue =
true;
16970 CheckLocationsExistInRailway))
16972 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16973 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16976 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
16978 OneLine = AnsiString(TrainTimetableString);
16984 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
16985 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
16991 OneLine = AnsiString(TrainTimetableString);
16996 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
16998 if(EndOfFile && (Count < 2))
17001 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
17006 delete TrainTimetableString;
17013 ShowMessage(
"Timetable secondary integrity check failed - unable to load");
17049 bool EndOfFile =
false;
17051 char *TrainTimetableString =
new char[10000];
17055 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17056 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17062 AnsiString OneLine(TrainTimetableString);
17063 bool FinalCallTrue =
true;
17065 CheckLocationsExistInRailway))
17067 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17068 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17071 throw Exception(
"Timetable FinalCall error - no start time on own line, Count = 0");
17073 OneLine = AnsiString(TrainTimetableString);
17079 TTBLFile.getline(TrainTimetableString, 10000,
'\0');
17080 if(TTBLFile.eof() && (TrainTimetableString[0] ==
'\0'))
17086 OneLine = AnsiString(TrainTimetableString);
17091 throw Exception(
"Timetable FinalCall error in processing one timetable line, Count = " + AnsiString(Count));
17093 if(EndOfFile && (Count < 2))
17096 throw Exception(
"Timetable FinalCall error - too few or no relevant entries, Count = " + AnsiString(Count));
17101 delete TrainTimetableString;
17133 std::ifstream InFile(FileName.c_str());
17135 int NumberOfActiveElements;
17136 bool GraphicsFollow =
false;
17138 if(InFile.is_open())
17285 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17291 if(TempString ==
"***BarriersDownVector***")
17329 ShowMessage(
"Session file failed to open - reason not known, unable to load session.");
17336 InFile.open(FileName.c_str());
17337 if(InFile.is_open())
17358 bool GraphicsFollow =
false;
17479 if((TempString !=
"***BarriersDownVector***") && (TempString !=
"***Timetable***"))
17485 if(TempString ==
"***BarriersDownVector***")
17564 InFile.get(TempChar);
17565 while(!InFile.eof() && ((TempChar ==
'\n') || (TempChar ==
'\0')))
17567 InFile.get(TempChar);
17598 double PowerDouble;
17628 AnsiString TempString =
"", Line1 =
"", Line2 =
"", Line3 =
"", Line4 =
"", Line5 =
"";
17629 char *Buffer =
new char[1000];
17632 InFile.get(TempChar);
17633 InFile.getline(Buffer, 1000);
17634 TempString = AnsiString(Buffer);
17635 while(TempString !=
"***End of performance file***")
17639 InFile.getline(Buffer, 1000);
17640 TempString = AnsiString(Buffer);
17651 AnsiString TempString =
"";
17654 InFile.get(TempChar);
17655 if(TempChar !=
'\n')
17665 while(TempString !=
"***End of performance file***")
17686 AnsiString OneLine = Text.SubString(1, Text.Pos(
'\x0D'));
17687 while((OneLine.Length() > 0) && OneLine[OneLine.Length()] <
' ')
17688 OneLine.SetLength(OneLine.Length() - 1);
17689 Text = Text.SubString(Text.Pos(
'\x0D'), Text.Length());
17690 while((Text.Length() > 0) && Text[1] <
' ')
17691 Text = Text.SubString(2, (Text.Length() - 1));
17692 OutFile << OneLine.c_str() <<
'\n';
17711 InfoPanel->Caption =
"PRE-START: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17713 InfoPanel->Caption =
"OPERATING: Select AUTOMATIC SIGNAL ROUTE start signal, or left click points to change manually";
17723 InfoPanel->Caption =
"PRE-START: Select PREFERRED ROUTE start signal, or left click points to change manually";
17725 InfoPanel->Caption =
"OPERATING: Select PREFERRED ROUTE start signal, or left click points to change manually";
17735 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17737 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17748 InfoPanel->Caption =
"PRE-START: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17750 InfoPanel->Caption =
"OPERATING: Select UNRESTRICTED ROUTE start location, or left click points to change manually";
17776 InfoPanel->Caption =
"Left click screen to zoom in at that position";
17781 InfoPanel->Caption =
"PAUSED: Railway state changes disabled";
17854 Screen->Cursor = TCursor(-11);
17855 AnsiString ErrorFileStr =
CurDir +
"\\errorlog.err";
17856 std::ofstream ErrorFile(ErrorFileStr.c_str());
17858 if(!(ErrorFile.fail()))
17861 int ScreenX = Mouse->CursorPos.x -
MainScreen->ClientOrigin.x;
17862 int ScreenY = Mouse->CursorPos.y -
MainScreen->ClientOrigin.y;
17863 AnsiString MouseStr =
"Posx: " + AnsiString(ScreenX) +
"; Posy: " + AnsiString(ScreenY);
17873 ErrorFile << Item.c_str() <<
'\n';
17880 ErrorFile << Item.c_str() <<
'\n';
17989 Screen->Cursor = TCursor(-2);
18006 int TempTTFileNumber = 0;
18008 while(FileExists(
CurDir +
"\\TmpTT" + AnsiString(TempTTFileNumber) +
".tmp"))
18010 TempTTFileNumber++;
18013 int InHandle = FileOpen(InFileName, fmOpenRead);
18016 while(InHandle < 0)
18018 InHandle = FileOpen(InFileName, fmOpenRead);
18023 ShowMessage(
"Failed to open timetable file, make sure it's not open in another application");
18031 while(OutHandle < 0)
18038 ShowMessage(
"Failed to save temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
18039 FileClose(InHandle);
18044 int CountIn, CountOut;
18045 char *Buffer =
new char[10000];
18049 CountIn = FileRead(InHandle, Buffer, 10000);
18050 CountOut = FileWrite(OutHandle, Buffer, CountIn);
18051 if(CountOut != CountIn)
18053 ShowMessage(
"Error in writing to the temporary timetable file, sessions can't be saved - try again, may only be a temporary problem");
18055 FileClose(InHandle);
18056 FileClose(OutHandle);
18060 if(CountIn < 10000)
18064 FileClose(InHandle);
18065 FileClose(OutHandle);
18110 int VarElements = 0;
18111 bool NamedLocPresent =
false;
18119 throw Exception(
"Error - failed to find track element at " + AnsiString(TE.
HLoc) +
" & " + AnsiString(TE.
VLoc) +
" in SetLengths");
18126 NamedLocPresent =
true;
18132 if(SpeedLimit != -1)
18137 if(SpeedLimit != -1)
18147 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) < 50))
18149 ShowMessage(
"Note: Named location elements are quite short. If they are too short the simulation might depart too far from reality.");
18152 if((NamedLocPresent) && (VarElements > 0) && ((Distance / VarElements) > 200))
18154 ShowMessage(
"Note: Named location elements are quite long. If they are too long the simulation might depart too far from reality.");
18163 if((VarElements * 20) > Distance)
18165 ShowMessage(
"Required distance is less than the minimum, will set each element to the minimum (20m)");
18166 Distance = (VarElements * 20);
18168 if(VarElements == 0)
18171 ShowMessage(
"No elements selected");
18177 int RemainingDistance = Distance, RemainingVarElements = VarElements, NextLength = RemainingDistance / VarElements;
18185 if(NextLength < 20)
18209 RemainingDistance -= NextLength;
18210 RemainingVarElements--;
18211 if(RemainingVarElements > 0)
18212 NextLength = RemainingDistance / RemainingVarElements;
18237 ShowMessage(
"Nothing to save!");
18242 SaveRailwayDialog->Filter =
"Development file (*.dev)|*.dev|Railway file (*.rly)|*.rly";
18253 Screen->Cursor = TCursor(-11);
18255 AnsiString Extension =
"";
18263 if(!(VecFile.fail()))
18291 if((LastChar ==
'y') || (LastChar ==
'Y'))
18319 ShowMessage(
"File open failed prior to save");
18323 ShowMessage(
"Can't save: extension must be either '.dev', or '.rly' with railway ready for operation");
18325 Screen->Cursor = TCursor(-2);
18423 bool TextFound =
false;
18446 AnsiString(VPos) +
"," + AnsiString((
short)UseEnteredPosition));
18447 int VPosHi, VPosLo, TextPosHi, TextPosLo;
18450 if(!UseEnteredPosition)
18457 int Depth = abs(Font->Height);
18458 TextPosHi = VPosHi + 20;
18459 TextPosLo = VPosLo - Depth - 4;
18462 if(TextPosLo >= ScreenPosLo)
18464 else if(TextPosHi < ScreenPosHi)
18467 VPos = ScreenPosLo + 288;
18513 catch(
const Exception &e)
18590 AnsiString OpTimeToActDisplay;
18591 AnsiString OpTimeToActString;
18592 AnsiString HeadCode;
18593 float OpTimeToActFloat;
18605 HeadCode = HCandTrainPosParam.first;
18606 if(OpTimeToActFloat < 0.25)
18608 OpTimeToActString =
"NOW";
18610 else if(OpTimeToActFloat < 1)
18612 OpTimeToActString =
"<1";
18616 OpTimeToActString = AnsiString(floor(OpTimeToActFloat));
18618 if(OpTimeToActFloat < 60)
18620 OpTimeToActDisplay = HeadCode + AnsiString(
'\t') + OpTimeToActString;
18621 OAListBox->Items->Add(OpTimeToActDisplay);
18645 TPicture *PicPtr =
new TPicture;
18647 UGME.second = PicPtr;
18658 catch(
const EInvalidGraphic &e)
18661 "Incorrect file format, the file can't be loaded.\nEnsure that the file you want is a valid graphic file with extension .bmp, .gif, .jpg, or .png");
18663 catch(
const Exception &e)